Class: RGame::Engine::Components::TileWorld
- Inherits:
-
RGame::Engine::Component
- Object
- RGame::Engine::Component
- RGame::Engine::Components::TileWorld
- Defined in:
- lib/rgame/engine/components/tile_world.rb
Overview
The scene-scoped tile world: a system component (it lives on the scene node and is found with node.system(TileWorld)) that owns the parsed Engine::TileMap and everything an actor needs from it — collision against the solid tiles, the world bounds, and drawing the map through the scene's camera.
Collision reuses Engine::CollisionSystem (TileCollision + a world-bounds clamp); the tile solidity is whatever the map's tileset reports (baked per-tile in Tiled).
It does not draw. Drawing the map is RGame::Engine::TileMapLayer, one node per Tiled layer, mounted inside the WorldView so the map is drawn once per viewport like the rest of the world. This stays a system — the thing actors ask about collision and bounds — and a system that also drew was always the odd part of it.
It owns the map's animation clock. Nothing below reads a wall clock —
see CLAUDE.md, "draw renders state; time enters through update" — so the
elapsed seconds animated tiles run on are accumulated here and handed down at
draw time. Stop calling update and the water freezes, which is what pausing
should look like.
Instance Attribute Summary collapse
-
#elapsed ⇒ Object
readonly
Returns the value of attribute elapsed.
-
#tilemap_id ⇒ Object
readonly
Returns the value of attribute tilemap_id.
Attributes inherited from RGame::Engine::Component
Instance Method Summary collapse
-
#bound(camera) ⇒ Object
Clamp a camera to this map's edges.
-
#first_above_layer ⇒ Object
The first layer Tiled flags
above, or the layer count if none is — which is where TileMapLayer.mount leaves the gap for the actors, so a map with no flag puts them over everything. -
#initialize(map:, tilemap_id:, cameras: []) ⇒ TileWorld
constructor
camerasare the cameras this map bounds — every player's, normally. - #layer_count ⇒ Object
-
#move(actor, dx, dy) ⇒ Object
Move an actor (responds to x/y/collision_box) by (dx, dy), sliding along solids and clamped inside the world.
- #solid?(col, row) ⇒ Boolean
-
#update(dt) ⇒ Object
Advances the tile animations.
- #world_height ⇒ Object
- #world_width ⇒ Object
Methods inherited from RGame::Engine::Component
#context, #control, #draw, #on_attach, #on_detach, #sweep_freed
Methods included from Signal::DSL
Constructor Details
#initialize(map:, tilemap_id:, cameras: []) ⇒ TileWorld
cameras are the cameras this map bounds — every player's, normally.
A camera may not show past the world's edges, and this is what knows
how big the world is; the cameras themselves are owned by players.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/rgame/engine/components/tile_world.rb', line 31 def initialize(map:, tilemap_id:, cameras: []) super() @map = map @tilemap_id = tilemap_id @elapsed = 0.0 Array(cameras).each { |camera| bound(camera) } @collision = Engine::CollisionSystem.new( tile_collision: Engine::TileCollision.new( tile_width: map.tile_width, tile_height: map.tile_height, solid: ->(col, row) { map.solid_tile?(col, row) } ), world_width: map.pixel_width, world_height: map.pixel_height ) end |
Instance Attribute Details
#elapsed ⇒ Object (readonly)
Returns the value of attribute elapsed.
26 27 28 |
# File 'lib/rgame/engine/components/tile_world.rb', line 26 def elapsed @elapsed end |
#tilemap_id ⇒ Object (readonly)
Returns the value of attribute tilemap_id.
26 27 28 |
# File 'lib/rgame/engine/components/tile_world.rb', line 26 def tilemap_id @tilemap_id end |
Instance Method Details
#bound(camera) ⇒ Object
Clamp a camera to this map's edges. Called for each camera the scene hands over, and again for one that arrives later (a player joining).
62 63 64 65 66 |
# File 'lib/rgame/engine/components/tile_world.rb', line 62 def bound(camera) camera.world_width = @map.pixel_width camera.world_height = @map.pixel_height camera end |
#first_above_layer ⇒ Object
The first layer Tiled flags above, or the layer count if none is —
which is where TileMapLayer.mount leaves the gap for the actors, so a
map with no flag puts them over everything. Read once at mount rather
than per frame: which layers cover the actors is a fact about the
scene's arrangement, and the arrangement is made once.
56 57 58 |
# File 'lib/rgame/engine/components/tile_world.rb', line 56 def first_above_layer layer_count.times.find { |index| @map.above_layer?(index) } || layer_count end |
#layer_count ⇒ Object
49 |
# File 'lib/rgame/engine/components/tile_world.rb', line 49 def layer_count = @map.layer_count |
#move(actor, dx, dy) ⇒ Object
Move an actor (responds to x/y/collision_box) by (dx, dy), sliding along solids and clamped inside the world. Delegates to the reused collision system.
70 |
# File 'lib/rgame/engine/components/tile_world.rb', line 70 def move(actor, dx, dy) = @collision.move(actor, dx, dy) |
#solid?(col, row) ⇒ Boolean
72 |
# File 'lib/rgame/engine/components/tile_world.rb', line 72 def solid?(col, row) = @map.solid_tile?(col, row) |
#update(dt) ⇒ Object
Advances the tile animations. Seconds, like every other duration here.
75 76 77 |
# File 'lib/rgame/engine/components/tile_world.rb', line 75 def update(dt) @elapsed += dt end |
#world_height ⇒ Object
47 |
# File 'lib/rgame/engine/components/tile_world.rb', line 47 def world_height = @map.pixel_height |
#world_width ⇒ Object
46 |
# File 'lib/rgame/engine/components/tile_world.rb', line 46 def world_width = @map.pixel_width |