Class: RGame::Engine::Tileset

Inherits:
Object
  • Object
show all
Defined in:
lib/rgame/engine/tileset.rb

Overview

Tile-type data parsed from a Tiled .tsx (pure; no graphics). Knows tile geometry, sheet columns, per-tile animations, and which tiles are solid. Solidity is baked into the asset: a tile is solid when it carries a Tiled collision shape (a per-tile <objectgroup> with at least one object), authored in Tiled's collision editor — so the map owns its collision, not the engine. solid_ids stays writable for games that want to override or augment it. Animation frames resolve from elapsed time so the renderer stays a thin layer.

Defined Under Namespace

Classes: Frame

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(firstgid:, columns:, tile_width:, tile_height:, image_source:, animations:, solid_ids: Set.new) ⇒ Tileset

Returns a new instance of Tileset.



60
61
62
63
64
65
66
67
68
# File 'lib/rgame/engine/tileset.rb', line 60

def initialize(firstgid:, columns:, tile_width:, tile_height:, image_source:, animations:, solid_ids: Set.new)
  @firstgid = firstgid
  @columns = columns
  @tile_width = tile_width
  @tile_height = tile_height
  @image_source = image_source
  @animations = animations
  @solid_ids = solid_ids
end

Instance Attribute Details

#animationsObject (readonly)

Returns the value of attribute animations.



17
18
19
# File 'lib/rgame/engine/tileset.rb', line 17

def animations
  @animations
end

#columnsObject (readonly)

Returns the value of attribute columns.



17
18
19
# File 'lib/rgame/engine/tileset.rb', line 17

def columns
  @columns
end

#firstgidObject (readonly)

Returns the value of attribute firstgid.



17
18
19
# File 'lib/rgame/engine/tileset.rb', line 17

def firstgid
  @firstgid
end

#image_sourceObject (readonly)

Returns the value of attribute image_source.



17
18
19
# File 'lib/rgame/engine/tileset.rb', line 17

def image_source
  @image_source
end

#solid_idsObject

Set of local tile ids treated as solid



18
19
20
# File 'lib/rgame/engine/tileset.rb', line 18

def solid_ids
  @solid_ids
end

#tile_heightObject (readonly)

Returns the value of attribute tile_height.



17
18
19
# File 'lib/rgame/engine/tileset.rb', line 17

def tile_height
  @tile_height
end

#tile_widthObject (readonly)

Returns the value of attribute tile_width.



17
18
19
# File 'lib/rgame/engine/tileset.rb', line 17

def tile_width
  @tile_width
end

Class Method Details

.collision_shape?(tile_el) ⇒ Boolean

A tile is solid if it carries a Tiled collision shape — an <objectgroup> with at least one object (the per-tile collision editor's output).

Returns:

  • (Boolean)


55
56
57
58
# File 'lib/rgame/engine/tileset.rb', line 55

def self.collision_shape?(tile_el)
  group = tile_el.elements['objectgroup']
  !group.nil? && !group.elements['object'].nil?
end

.parse(tsx_string, firstgid:) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rgame/engine/tileset.rb', line 20

def self.parse(tsx_string, firstgid:)
  root = REXML::Document.new(tsx_string).root

  animations = {}
  solid = Set.new
  root.each_element('tile') do |tile_el|
    id = tile_el.attributes['id'].to_i
    animations[id] = parse_animation(tile_el)
    solid << id if collision_shape?(tile_el)
  end
  animations.compact!

  new(
    firstgid: firstgid,
    columns: root.attributes['columns'].to_i,
    tile_width: root.attributes['tilewidth'].to_i,
    tile_height: root.attributes['tileheight'].to_i,
    image_source: root.elements['image'].attributes['source'],
    animations: animations,
    solid_ids: solid
  )
end

.parse_animation(tile_el) ⇒ Object

Frames for an animated tile, or nil (compacted away) for a static one.



44
45
46
47
48
49
50
51
# File 'lib/rgame/engine/tileset.rb', line 44

def self.parse_animation(tile_el)
  anim = tile_el.elements['animation']
  return unless anim

  anim.get_elements('frame').map do |f|
    Frame.new(f.attributes['tileid'].to_i, f.attributes['duration'].to_i)
  end
end

Instance Method Details

#animated_idsObject



70
71
72
# File 'lib/rgame/engine/tileset.rb', line 70

def animated_ids
  @animations.keys
end

#frame_local_id(local, ms) ⇒ Object

The local tile id to draw for local at time ms, following its animation (or local itself if the tile isn't animated).



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rgame/engine/tileset.rb', line 86

def frame_local_id(local, ms)
  frames = @animations[local]
  return local unless frames

  total = frames.sum(&:duration)
  t = ms % total
  frames.each do |frame|
    return frame.tile_id if t < frame.duration

    t -= frame.duration
  end
  frames.last.tile_id
end

#local_id(gid) ⇒ Object



74
75
76
# File 'lib/rgame/engine/tileset.rb', line 74

def local_id(gid)
  gid - @firstgid
end

#solid?(gid) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
81
82
# File 'lib/rgame/engine/tileset.rb', line 78

def solid?(gid)
  return false if gid.zero?

  @solid_ids.include?(local_id(gid))
end