class_name Avatar extends Node2D ## The local player's figure. It moves outside the lockstep simulation; only ## its pickaxe hits become commands. `art` draws it, stepping while it walks ## and facing the way it went last. ## Walking speed: five tiles per second. const SPEED := 5.0 * GridMotion.TILE_SIZE const RADIUS := 5.0 ## Longest frame that moves the figure in one go. Longer frames are cut, so ## that the figure cannot pass through a wall after a stall. const MAX_STEP_SECONDS := 0.1 ## How far the step of a walking figure turns per pixel, in radians: about ## two steps per second at walking speed. const STEP_PER_PIXEL := 0.16 ## Callable(x: int, y: int) -> bool that says whether a tile can be walked on. var is_walkable: Callable var art: Art ## The number of the player the figure belongs to, for its colour, or -1 ## before the player is in the world. var player := -1 ## 1.0 while the figure faces right, -1.0 while it faces left. var facing := 1.0 ## Grows while the figure walks; the styles swing the steps by it. var step := 0.0 ## True while the figure walked in the last frame. var moving := false ## Where a figure standing at `at` is drawn: a tile wide and one and a half ## tiles tall, with its feet just below its body, so that it stands upright ## in its tile. static func figure_rect(at: Vector2) -> Rect2: var size := GridMotion.TILE_SIZE return Rect2(at.x - size / 2.0, at.y + RADIUS + 1.0 - size * 1.5, size, size * 1.5) func _process(delta: float) -> void: walk(Input.get_vector("move_left", "move_right", "move_up", "move_down"), delta) ## Moves the figure in `direction` for `delta` seconds, sliding along walls. func walk(direction: Vector2, delta: float) -> void: var was_moving := moving moving = false if direction == Vector2.ZERO or not is_walkable.is_valid(): if was_moving: queue_redraw() return var motion := direction * SPEED * minf(delta, MAX_STEP_SECONDS) var before := position position = GridMotion.move(position, motion, RADIUS, is_walkable) var walked := position.distance_to(before) moving = walked > 0.0 step += walked * STEP_PER_PIXEL if direction.x != 0.0: facing = signf(direction.x) queue_redraw() func _draw() -> void: if art != null: art.draw(self, Art.FIGURE, figure_rect(Vector2.ZERO), {"player": player, "facing": facing, "step": step, "moving": moving})