Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 61 additions & 21 deletions game_demos/DrawingTurtle.gd
Original file line number Diff line number Diff line change
Expand Up @@ -52,37 +52,50 @@ func _ready() -> void:

# Virtually moves the turtle and records a new vertex.
func move_forward(distance: float) -> void:
var previous_point := Vector2.ZERO
_handle_position_setting()
if _points.empty():
_points.append(previous_point)
else:
previous_point = _points[-1]
var new_point := previous_point + Vector2.RIGHT.rotated(deg2rad(turn_degrees)) * distance
_points.append(Vector2.ZERO)

var new_point := position + Vector2.RIGHT.rotated(deg2rad(turn_degrees)) * distance
new_point = new_point.snapped(Vector2.ONE)
_points.append(new_point)
position = new_point

_temp_command_stack.append(
{command = "move_to", target = new_point + position + _current_offset}
{command = "move_to", target = new_point}
)

# Check if the polygon has vertices that align. In that case, we consider it
# closed.
if _points.size() > 1:
var last_point = _points[-1]
for i in range(_points.size() - 1):
if _points[i].is_equal_approx(last_point):
_close_polygon()
break


func turn_right(angle_degrees: float) -> void:
_handle_position_setting()
turn_degrees = round(turn_degrees + angle_degrees)
_temp_command_stack.append({command = "turn", angle = round(angle_degrees)})


func turn_left(angle_degrees: float) -> void:
_handle_position_setting()
turn_degrees = round(turn_degrees - angle_degrees)
_temp_command_stack.append({command = "turn", angle = round(-angle_degrees)})


# Completes the current polygon's drawing and virtually jumps the turtle to a
# new start position.
func jump(x: float, y: float) -> void:
_handle_position_setting()
var last_point := Vector2.ZERO if _points.empty() else _points[-1]
_close_polygon()
_points.append(Vector2.ZERO)
_current_offset += Vector2(x, y) + last_point

position += Vector2(x, y)
_points.append(position)

_command_stack.append({command = "jump", offset = Vector2(x, y)})

Expand All @@ -103,7 +116,7 @@ func reset() -> void:
_polygons.clear()
for child in _canvas.get_children():
child.queue_free()
_current_offset = Vector2.ZERO
position = Vector2.ZERO
_pivot.position = Vector2.ZERO


Expand All @@ -126,7 +139,7 @@ func play_draw_animation() -> void:
# We queue all tweens at once, based on commands: moving the turtle, turning
# it, drawing lines...
var tween_start_time := 0.0
var turtle_position := position
var turtle_position := Vector2.ZERO
var turtle_rotation_degrees := rotation_degrees
for command in _command_stack:
var duration := 1.0
Expand All @@ -135,28 +148,30 @@ func play_draw_animation() -> void:
turtle_position = command.target
_pivot.position = command.target
"move_camera":
print("Moving the camera to " + str(command.target))
# The callback never gets called if it has a delay of 0 seconds.
if is_equal_approx(tween_start_time, 0.0):
_move_camera(command.target)
else:
_tween.interpolate_callback(
self, tween_start_time, "_move_camera", command.target
)
print("interpolating...")
"move_to":
duration = turtle_position.distance_to(command.target) / draw_speed / speed_multiplier
_tween.interpolate_property(
_pivot,
"position",
turtle_position - position,
command.target - position,
turtle_position,
command.target,
duration,
Tween.TRANS_LINEAR,
Tween.EASE_IN,
tween_start_time
)
var line := DrawingLine2D.new(
turtle_position - position,
command.target - position,
turtle_position,
command.target,
duration,
tween_start_time
)
Expand Down Expand Up @@ -232,27 +247,44 @@ func _animate_jump(progress: float) -> void:


func _close_polygon() -> void:
if _points.empty():
if _points.size() <= 1:
_points.clear()
for command in _temp_command_stack:
_command_stack.append(command)
_temp_command_stack.clear()
return

var polygon := Polygon.new()
# We want to test shapes being drawn at the correct position using the
# position property. It works differently from jump() which offsets the
# turtle from its position.
polygon.position = position + _current_offset
polygon.position = position
polygon.points = PoolVector2Array(_points)
_polygons.append(polygon)
_points.clear()

if not position.is_equal_approx(Vector2.ZERO):
_command_stack.append({command = "set_position", target = position})
# We can't know exactly when and where to move the camera until completing a
# shape, as we want to center the camera on the shape.
_command_stack.append({command = "move_camera", target = polygon.get_center()})
_command_stack.append({command = "move_camera", target = polygon.get_center() + global_position})
for command in _temp_command_stack:
_command_stack.append(command)
_temp_command_stack.clear()

func _handle_position_setting() -> void:
# When the user accesses and adjusts the position variable directly, we must
# detect this, close the polygon, and add to the command stack.
if _points.empty() and position.is_equal_approx(Vector2.ZERO):
return

var previous_point = Vector2.ZERO
if not _points.empty():
previous_point = _points[-1]
if not position.is_equal_approx(previous_point):
_command_stack.append({command = "move_camera", target = position + global_position})
_temp_command_stack.append({command = "set_position", target = position})
_close_polygon()
_points.append(position)


func _move_camera(target_global_position: Vector2) -> void:
_camera.position = target_global_position
Expand All @@ -269,7 +301,8 @@ class Polygon:
func get_rect() -> Rect2:
var top_left := Vector2.ZERO
var bottom_right := Vector2.ZERO
for p in points:
var local_points = get_points()
for p in local_points:
if p.x > bottom_right.x:
bottom_right.x = p.x
elif p.x < top_left.x:
Expand All @@ -295,7 +328,14 @@ class Polygon:
return (rect.position + rect.end) / 2.0 + global_position

func get_points() -> PoolVector2Array:
return points
var local_points = []
var first_point = Vector2.ZERO
if not points.empty():
first_point = points[0]

for point in points:
local_points.append(point - first_point)
return local_points

func is_empty():
return points.empty() or points == PoolVector2Array([Vector2.ZERO])
Expand Down