d2a7973022
Karte, Figuren und Zielmarke zeichnet jetzt Art. Die Karte zeichnet in Blöcken von 16 mal 16 Kacheln und nach einem Treffer nur die Blöcke um die Kachel neu; jede Kachel kennt ihre Nachbarn. Figuren stehen aufrecht in ihrer Kachel, schreiten und schauen in die Richtung, in die sie gehen. Der eigene Schlag zeigt seine Splitter sofort, auch als Gast, und die Namen über fremden Figuren werden in Bildschirmgröße gezeichnet und bleiben scharf. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
65 lines
2.3 KiB
GDScript
65 lines
2.3 KiB
GDScript
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})
|