Takt und Bewegung der Figur
TickClock rechnet Bildzeit in Takte um und holt nach einem Ruckler höchstens fünf Takte auf. GridMotion bewegt einen Körper über das Kachelraster und lässt ihn an Wänden entlanggleiten. Die Figur läuft fünf Felder pro Sekunde, außerhalb des Gleichschritts. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
class_name GridMotion
|
||||
extends RefCounted
|
||||
## Movement of a body over the tile grid. Figures move outside the lockstep
|
||||
## simulation, so this code may use floating point.
|
||||
|
||||
## Edge length of a tile, in pixels.
|
||||
const TILE_SIZE := 16.0
|
||||
|
||||
|
||||
## The tile that contains `point`.
|
||||
static func tile_of(point: Vector2) -> Vector2i:
|
||||
return Vector2i(floori(point.x / TILE_SIZE), floori(point.y / TILE_SIZE))
|
||||
|
||||
|
||||
## The centre of `tile`, in pixels.
|
||||
static func tile_center(tile: Vector2i) -> Vector2:
|
||||
return (Vector2(tile) + Vector2(0.5, 0.5)) * TILE_SIZE
|
||||
|
||||
|
||||
## True if a square body of half width `radius` around `center` touches
|
||||
## only walkable tiles. `is_walkable` is a Callable(x: int, y: int) -> bool.
|
||||
static func fits(center: Vector2, radius: float, is_walkable: Callable) -> bool:
|
||||
var first := tile_of(center - Vector2(radius, radius))
|
||||
# The far edge lies just inside its tile, so a body that ends exactly on
|
||||
# a tile border does not count the next tile.
|
||||
var last := tile_of(center + Vector2(radius, radius) - Vector2(0.001, 0.001))
|
||||
for y in range(first.y, last.y + 1):
|
||||
for x in range(first.x, last.x + 1):
|
||||
if not is_walkable.call(x, y):
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
## Moves a body by `motion`, one axis after the other. An axis that would
|
||||
## end in a wall is skipped, so a body pushed into a wall slides along it.
|
||||
static func move(center: Vector2, motion: Vector2, radius: float, is_walkable: Callable) -> Vector2:
|
||||
var result := center
|
||||
var along_x := result + Vector2(motion.x, 0.0)
|
||||
if fits(along_x, radius, is_walkable):
|
||||
result = along_x
|
||||
var along_y := result + Vector2(0.0, motion.y)
|
||||
if fits(along_y, radius, is_walkable):
|
||||
result = along_y
|
||||
return result
|
||||
Reference in New Issue
Block a user