diff --git a/godot_ship/scenes/Gameplay.tscn b/godot_ship/scenes/Gameplay.tscn index c9f727e..b820cb7 100644 --- a/godot_ship/scenes/Gameplay.tscn +++ b/godot_ship/scenes/Gameplay.tscn @@ -99,8 +99,3 @@ contact_monitor = true [connection signal="pressed" from="VBoxContainer/Forfeit" to="." method="_on_Forfeit_pressed"] [connection signal="about_to_show" from="ConfirmationDialog" to="." method="_on_ConfirmationDialog_about_to_show"] -[connection signal="body_entered" from="2Ship" to="." method="_on_2Ship_body_entered"] -[connection signal="body_entered" from="3ShipA" to="." method="_on_3ShipA_body_entered"] -[connection signal="body_entered" from="3ShipB" to="." method="_on_3ShipB_body_entered"] -[connection signal="body_entered" from="4Ship" to="." method="_on_4Ship_body_entered"] -[connection signal="body_entered" from="5Ship" to="." method="_on_5Ship_body_entered"] diff --git a/godot_ship/script/game/Gameplay.gd b/godot_ship/script/game/Gameplay.gd index 573a793..8b00fae 100644 --- a/godot_ship/script/game/Gameplay.gd +++ b/godot_ship/script/game/Gameplay.gd @@ -1,48 +1,13 @@ extends Control -signal two_ship_collide -signal three_shipA_collide -signal three_shipB_collide -signal four_ship_collide -signal five_ship_collide - -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" - # Called when the node enters the scene tree for the first time. func _ready(): if find_next_valid_focus(): find_next_valid_focus().grab_focus() -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass - func _on_Forfeit_pressed(): AudioBus.emit_signal("button_clicked") queue_free(); MessageBus.emit_signal("change_scene", "Title") - -func _on_2Ship_body_entered(body): - var _errno = emit_signal("two_ship_collide", "2Ship") - print("Emitting two_ship_collide") - -func _on_3ShipA_body_entered(body): - emit_signal("three_shipA_collide", "3ShipA") - print("Emitting three_shipA_collide") - -func _on_3ShipB_body_entered(body): - emit_signal("three_shipB_collide", "3ShipA") - print("Emitting three_shipB_collide") - -func _on_4Ship_body_entered(body): - emit_signal("four_ship_collide", "4Ship") - print("Emitting four_ship_collide") - -func _on_5Ship_body_entered(body): - emit_signal("five_ship_collide", "5Ship") - print("Emitting five_ship_collide") - diff --git a/godot_ship/script/game/moveShip.gd b/godot_ship/script/game/moveShip.gd index 1e03052..74c2fe6 100644 --- a/godot_ship/script/game/moveShip.gd +++ b/godot_ship/script/game/moveShip.gd @@ -1,110 +1,59 @@ extends RigidBody2D -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" + var held = false var originalPos var snapOriginalPos = false +var mousePos var vertical = true var startingPos +# Ships are all named starting with their length, +# So we cast from string to int, on the ship name, and get the length +onready var ship_length = int(name) + +var collision = false + # Called when the node enters the scene tree for the first time. func _ready(): + mode = MODE_KINEMATIC + # Snap the ships to the grid, so the engine won't get mad when they're moved away from the starting position every frame + position = (position - offset).snapped(Vector2(32, 32)) + offset startingPos = position - var _errno = 0 - _errno = find_parent("Game").connect("two_ship_collide", self, "if_ship_stacked") - _errno = find_parent("Game").connect("three_shipA_collide", self, "if_ship_stacked") - _errno = find_parent("Game").connect("three_shipB_collide", self, "if_ship_stacked") - _errno = find_parent("Game").connect("four_ship_collide", self, "if_ship_stacked") - _errno = find_parent("Game").connect("five_ship_collide", self, "if_ship_stacked") + var _trash + # Connect to my own signals, and not the signals of my fellowships + # PLEASE don't parameterize; there's no way to tell these signals apart with the args the engine provides. + _trash = connect("body_entered", self, "ship_stacked") + _trash = connect("body_exited", self, "ship_unstacked") +# Radius of the "knob" on the center of each ship var click_radius = 16 -var orient = 0; func _input(event): if event is InputEventMouseButton and event.button_index == BUTTON_LEFT: if (event.position - position).length() < click_radius: if not held and event.pressed: AudioBus.emit_signal("button_clicked") - held = true; + pickup() if held and not event.pressed: - held = false; - if (position.x > 17.4 and position.x < 335.5) and (position.y > 20.2 and position.y < 335.5): - position = position.snapped(Vector2(32, 32)) + Vector2(4, 4) - else: + drop() + # Convert the center of this piece to board-space + var bs_position = world_to_board_space(position) + # Check whether the piece is within half a board-space of the grid (-0.5, 9.5) + if not (bs_position.x > -0.5 and bs_position.x < 9.5 and bs_position.y > -0.5 and bs_position.y < 9.5): +# if not (position.x > 17.4 and position.x < 335.5) and (position.y > 20.2 and position.y < 335.5): if originalPos != null: - position = originalPos + collision = true rotation = 0 vertical = true - - # 2-Ship - if (get_parent().get_node("2Ship").rotation_degrees == 0): - if (get_parent().get_node("2Ship").position.y > 308): - position = originalPos - rotation = 0 - vertical = true - if (get_parent().get_node("2Ship").rotation_degrees == -90): - if (get_parent().get_node("2Ship").position.x > 308): - position = originalPos - rotation = 0 - vertical = true - - # 3-Ship A - if (get_parent().get_node("3ShipA").rotation_degrees == 0): - if (get_parent().get_node("3ShipA").position.y > 308) or (get_parent().get_node("3ShipA").position.y < 52): - position = originalPos - rotation = 0 - vertical = true - if (get_parent().get_node("3ShipA").rotation_degrees == -90): - if (get_parent().get_node("3ShipA").position.x > 308) or (get_parent().get_node("3ShipA").position.x < 52): - position = originalPos - rotation = 0 - vertical = true - - # 3-Ship B - if (get_parent().get_node("3ShipB").rotation_degrees == 0): - if (get_parent().get_node("3ShipB").position.y > 308) or (get_parent().get_node("3ShipB").position.y < 52): - position = originalPos - rotation = 0 - vertical = true - if (get_parent().get_node("3ShipB").rotation_degrees == -90): - if (get_parent().get_node("3ShipB").position.x > 308) or (get_parent().get_node("3ShipB").position.x < 52): - position = originalPos - rotation = 0 - vertical = true - - # 4-Ship - if (get_parent().get_node("4Ship").rotation_degrees == 0): - if (get_parent().get_node("4Ship").position.y > 276.8) or (get_parent().get_node("4Ship").position.y < 52): - position = originalPos - rotation = 0 - vertical = true - if (get_parent().get_node("4Ship").rotation_degrees == -90): - if (get_parent().get_node("4Ship").position.x > 276.8) or (get_parent().get_node("4Ship").position.x < 52): - position = originalPos - rotation = 0 - vertical = true - - # 5-Ship - if (get_parent().get_node("5Ship").rotation_degrees == 0): - if (get_parent().get_node("5Ship").position.y > 276.8) or (get_parent().get_node("5Ship").position.y < 84.8): - position = originalPos - rotation = 0 - vertical = true - if (get_parent().get_node("5Ship").rotation_degrees == -90): - if (get_parent().get_node("5Ship").position.x > 276.8) or (get_parent().get_node("5Ship").position.x < 84.8): - position = originalPos - rotation = 0 - vertical = true - - + if event is InputEventMouseMotion and held: if snapOriginalPos == false: originalPos = position snapOriginalPos = true - position = event.position; + # Save the moise position, so _physics_process can use it + mousePos = event.position; if event.is_action_pressed("ui_rotate"): if held: @@ -112,117 +61,133 @@ func _input(event): if checkOriginalPos(): return else: - AudioBus.emit_signal("button_clicked") + AudioBus.emit_signal("button_clicked") if originalPos == null: if position == originalPos: return elif(event.position - position).length() < click_radius: - if vertical == true: - rotation = (-PI/2) - vertical = false - else: - rotation = 0 - vertical = true + # Rotation has been moved to _physics_process, + # as per recommendation of godot_engine.org + #rotation = (-PI/2) + vertical = not vertical + + +# Offset from the corner of the screen to the corner of the board +const offset = Vector2(36, 36) +# The previous verticality of the object +var prev_vertical = true +# The previous position of the object +var prev_position = Vector2(0,0) +# The number of frames after an object is released to check for physics updates +var released = 0 + + +# _physics_process: called in place of the physics processor +# Checks collision and updates the position and rotation of the object +func _physics_process(_delta): + # calculate whether the piece has been rotated or moved + var rotated = prev_vertical != vertical + var moved = prev_position != position + + # If the piece is held, move it to the mouse: + if held and mousePos and mousePos != position: + position = mousePos + mousePos = null - if(position.x > 17.4 and position.x < 335.5) and (position.y > 20.2 and position.y < 335.5): - # 2-Ship - if (get_parent().get_node("2Ship").rotation_degrees == 0): - if (get_parent().get_node("2Ship").position.y > 308): - get_parent().get_node("2Ship").position.y -= 32 - if (get_parent().get_node("2Ship").rotation_degrees == -90): - if (get_parent().get_node("2Ship").position.x > 308): - get_parent().get_node("2Ship").position.x -= 32 + # Snap it to the grid if not held (and previously moved) + if not held and moved: + position = (position - offset).snapped(Vector2(32, 32)) + offset + prev_position = position - # 3-Ship A - if (get_parent().get_node("3ShipA").rotation_degrees == 0): - if (get_parent().get_node("3ShipA").position.y > 308): - get_parent().get_node("3ShipA").position.y -= 32 - if (get_parent().get_node("3ShipA").position.y < 52): - get_parent().get_node("3ShipA").position.y += 32 - if (get_parent().get_node("3ShipA").rotation_degrees == -90): - if (get_parent().get_node("3ShipA").position.x > 308): - get_parent().get_node("3ShipA").position.x -= 32 - if (get_parent().get_node("3ShipA").position.x < 52): - get_parent().get_node("3ShipA").position.x += 32 - - # 3-Ship B - if (get_parent().get_node("3ShipB").rotation_degrees == 0): - if (get_parent().get_node("3ShipB").position.y > 308): - get_parent().get_node("3ShipB").position.y -= 32 - if (get_parent().get_node("3ShipB").position.y < 52): - get_parent().get_node("3ShipB").position.y += 32 - if (get_parent().get_node("3ShipB").rotation_degrees == -90): - if (get_parent().get_node("3ShipB").position.x > 308): - get_parent().get_node("3ShipB").position.x -= 32 - if (get_parent().get_node("3ShipB").position.x < 52): - get_parent().get_node("3ShipB").position.x += 32 - - # 4-Ship - if (get_parent().get_node("4Ship").rotation_degrees == 0): - if (get_parent().get_node("4Ship").position.y > 308.8): - get_parent().get_node("4Ship").position.y -= 64; - elif (get_parent().get_node("4Ship").position.y > 276.8): - get_parent().get_node("4Ship").position.y -= 32; - if (get_parent().get_node("4Ship").position.y < 52): - get_parent().get_node("4Ship").position.y += 32 - if (get_parent().get_node("4Ship").rotation_degrees == -90): - if (get_parent().get_node("4Ship").position.x > 308.8): - get_parent().get_node("4Ship").position.x -= 64 - elif (get_parent().get_node("4Ship").position.x > 276.8): - get_parent().get_node("4Ship").position.x -= 32 - if (get_parent().get_node("4Ship").position.x < 52): - get_parent().get_node("4Ship").position.x += 32 - - # 5-Ship - if (get_parent().get_node("5Ship").rotation_degrees == 0): - if (get_parent().get_node("5Ship").position.y > 308.8): - get_parent().get_node("5Ship").position.y -= 64 - elif (get_parent().get_node("5Ship").position.y > 276.8): - get_parent().get_node("5Ship").position.y -= 32 - - if (get_parent().get_node("5Ship").position.y < 52): - get_parent().get_node("5Ship").position.y += 64 - elif (get_parent().get_node("5Ship").position.y < 84.8): - get_parent().get_node("5Ship").position.y += 32 - - if (get_parent().get_node("5Ship").rotation_degrees == -90): - if (get_parent().get_node("5Ship").position.x > 308.8): - get_parent().get_node("5Ship").position.x -= 64 - elif (get_parent().get_node("5Ship").position.x > 276.8): - get_parent().get_node("5Ship").position.x -= 32 - - if (get_parent().get_node("5Ship").position.x < 52): - get_parent().get_node("5Ship").position.x += 64 - elif (get_parent().get_node("5Ship").position.x < 84.8): - get_parent().get_node("5Ship").position.x += 32 + # Check collisions after released, reset if colliding + if collision and released: + position = startingPos -# Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass + # If it's been moved or rotated, snap it to the board + if released or rotated: + # check whether the ends of the piece are within the board + var linear_move = check_extents(position, vertical, ship_length) + # if not, move them back inside + if linear_move: + if vertical: + position += 32 * Vector2(0, linear_move) + else: + position += 32 * Vector2(linear_move, 0) + pass + + # Rotate if the piece needs to be rotated + if rotated: + prev_vertical = vertical + rotation = -PI/2 * int(not vertical) # int(true) == 1, int(false) == 0 + + # Count down the number of physics timesteps left until the piece can stop processing + if released > 0: + released = released - 1 + func pickup(): - if held: - return - mode = RigidBody2D.MODE_STATIC - held = true + if not held: + raise() # Render this ship on top of other ships + held = true # mark it as held + collision = false # Assume we're not colliding by default -func drop(impulse=Vector2.ZERO): +func drop(): if held: - mode = RigidBody2D.MODE_RIGID - apply_central_impulse(impulse) - held = false + released = 1 # mark the node as released + held = false # mark the node as not held snapOriginalPos = false - -func checkOriginalPos(): - if position == startingPos: - return true - else: - return false -func if_ship_stacked(ship): - if !held && ship == name: - position = startingPos - rotation = 0 - print("we colliding over here") - return - +func checkOriginalPos(): + return position == startingPos + + +# Called when *this* ship collides with another ship +func ship_stacked(_body): + collision = true +# Called when *this* ship stops colliding with another ship +func ship_unstacked(_body): + collision = false + +# Calculate the extents (front to back) of the ship and check whether they're on the board +# Returns how many squares to move the ship along its orientation axis (positive or negative) +func check_extents(center, orientation, length): + center = world_to_board_space(center) # Convert to board-space (0-10) + print("Center: ", center) + # Calculate the position of the front of the ship + # Orientation is true when the ship is vertical + var bow = vectorget(center, orientation) - floor((length - 1) / 2) + print("Bow: ", bow) + # if out of bounds, return how much to move the ship by + if bow < 0: + print("return: ", -bow) + return -bow + # Calculate the position of the rear of the ship + var stern = vectorget(center, orientation) + floor(length / 2) + print("Stern: ", stern) + # If out of bounds, return how much to move the ship by + if stern >= 10: + print("return: ", -(stern - 9)) + return -(stern - 9) + print("return: ", 0) + return 0 + +# Convert the world-space coordinates to positions on the board +func world_to_board_space(vector): + # Do math + var res = (vector - offset) / 32 # Subtract the distance between the screen corner and square (0,0) + return res + +# Inverse of the above function. +func board_to_world_space(vector): + # Do math + var res = (vector * 32) + offset #Invert the above function + return res #Truncate decimals + +# index a Vector2 like an array +# Why is this needed? +# So we can discard the unimportant axis! (a ship is always 1 unit wide!) +func vectorget(vector, axis): + if axis: + return vector.y + else: + return vector.x