Class: RGame::Engine::TileCollision
- Inherits:
-
Object
- Object
- RGame::Engine::TileCollision
- Defined in:
- lib/rgame/engine/tile_collision.rb
Overview
Axis-separated AABB-vs-tile collision resolution (pure). solid is a callable
solid.call(col, row) -> bool. Resolve X then Y (with the X result) to get
wall-sliding. Assumes per-step movement smaller than a tile (no tunneling),
which holds for our speeds.
Constant Summary collapse
- EPS =
1e-9
Instance Method Summary collapse
-
#initialize(tile_width:, tile_height:, solid:) ⇒ TileCollision
constructor
A new instance of TileCollision.
-
#resolve_x(x, y, w, h, dx) ⇒ Object
Move an AABB (top-left x, y; size w, h) by dx, snapping flush against solids.
- #resolve_y(x, y, w, h, dy) ⇒ Object
Constructor Details
#initialize(tile_width:, tile_height:, solid:) ⇒ TileCollision
Returns a new instance of TileCollision.
12 13 14 15 16 |
# File 'lib/rgame/engine/tile_collision.rb', line 12 def initialize(tile_width:, tile_height:, solid:) @tile_width = tile_width @tile_height = tile_height @solid = solid end |
Instance Method Details
#resolve_x(x, y, w, h, dx) ⇒ Object
Move an AABB (top-left x, y; size w, h) by dx, snapping flush against solids.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/rgame/engine/tile_collision.rb', line 19 def resolve_x(x, y, w, h, dx) nx = x + dx return nx if dx.zero? first_row = (y / @tile_height).floor last_row = ((y + h - EPS) / @tile_height).floor if dx.positive? col = ((nx + w - EPS) / @tile_width).floor return col * @tile_width - w if solid_in_rows?(col, first_row, last_row) else col = (nx / @tile_width).floor return (col + 1) * @tile_width if solid_in_rows?(col, first_row, last_row) end nx end |
#resolve_y(x, y, w, h, dy) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rgame/engine/tile_collision.rb', line 36 def resolve_y(x, y, w, h, dy) ny = y + dy return ny if dy.zero? first_col = (x / @tile_width).floor last_col = ((x + w - EPS) / @tile_width).floor if dy.positive? row = ((ny + h - EPS) / @tile_height).floor return row * @tile_height - h if solid_in_cols?(row, first_col, last_col) else row = (ny / @tile_height).floor return (row + 1) * @tile_height if solid_in_cols?(row, first_col, last_col) end ny end |