Class: SFML::TextureAtlas
- Inherits:
-
Object
- Object
- SFML::TextureAtlas
- Defined in:
- lib/sfml/graphics/texture_atlas.rb
Overview
A sprite-sheet plus a frame-name → rectangle index. Loads the
JSON descriptors that Aseprite and TexturePacker export — both
use the same frames + meta shape, just with a few field
differences we paper over.
atlas = SFML::TextureAtlas.load("hero.json")
atlas.texture #=> SFML::Texture
atlas.region("hero-walk-0") #=> SFML::Rect
atlas.frame_names #=> [...]
atlas.sprite("hero-walk-0") #=> ready-to-draw SFML::Sprite
atlas.duration("hero-walk-0") #=> Integer ms (Aseprite only)
The image path inside the JSON is resolved relative to the JSON
file's directory. Override with image: "path/to/img.png".
Frame lookups are tolerant of the .png extension — Aseprite
exports walk-0.png, but you can write atlas.region("walk-0").
Constant Summary collapse
- IMAGE_EXTS =
File-extension regex for atlas image files.
/\.(?:png|jpg|jpeg|bmp|tga|gif)\z/i
Instance Attribute Summary collapse
-
#source ⇒ Object
readonly
The texture, source components.
-
#texture ⇒ Object
readonly
The texture, source components.
Class Method Summary collapse
Instance Method Summary collapse
-
#animation(frame_names, fps: nil, loop: true) ⇒ Object
Build an Animation from a list of frame names.
-
#duration(name) ⇒ Object
Integer milliseconds per frame, as exported by Aseprite.
-
#frame_names ⇒ Object
Returns the frame names.
-
#initialize(texture:, regions:, durations: {}, source: nil) ⇒ TextureAtlas
constructor
Build directly from a Texture + a frame Hash — useful when generating atlases procedurally or when the descriptor lives in a different format you've already parsed.
-
#region(name) ⇒ SFML::Rect
The pixel rect for frame
name. -
#regions ⇒ Object
The internal frame-name → Rect hash.
-
#sprite(name, **opts) ⇒ Object
Build a fresh Sprite bound to the atlas texture with its texture_rect set to this frame.
-
#to_s ⇒ Object
(also: #inspect)
String representation for debugging.
Constructor Details
#initialize(texture:, regions:, durations: {}, source: nil) ⇒ TextureAtlas
Build directly from a Texture + a frame Hash — useful when generating atlases procedurally or when the descriptor lives in a different format you've already parsed.
43 44 45 46 47 48 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 43 def initialize(texture:, regions:, durations: {}, source: nil) @texture = texture @regions = regions.transform_keys { |k| _normalize(k) }.freeze @durations = durations.transform_keys { |k| _normalize(k) }.freeze @source = source end |
Instance Attribute Details
#source ⇒ Object (readonly)
The texture, source components.
51 52 53 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 51 def source @source end |
#texture ⇒ Object (readonly)
The texture, source components.
51 52 53 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 51 def texture @texture end |
Class Method Details
.load(json_path, image: nil, smooth: true) ⇒ TextureAtlas
30 31 32 33 34 35 36 37 38 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 30 def self.load(json_path, image: nil, smooth: true) data = JSON.parse(File.read(json_path)) image_path = image || File.(data.dig("meta", "image") || "", File.dirname(json_path)) raise LoadError, "TextureAtlas: image not found at #{image_path}" unless File.file?(image_path) texture = Texture.load(image_path, smooth: smooth) regions, durations = _parse_frames(data["frames"]) new(texture: texture, regions: regions, durations: durations, source: json_path) end |
Instance Method Details
#animation(frame_names, fps: nil, loop: true) ⇒ Object
Build an Animation from a list of frame names. When fps: is
nil and Aseprite-style duration data is present, the per-frame
durations are used directly — letting artists set timing in
Aseprite without re-tuning in code. Pass an explicit fps: to
override.
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 75 def animation(frame_names, fps: nil, loop: true) rects = frame_names.map { |n| region(n) } if fps.nil? && frame_names.first && duration(frame_names.first) > 0 # Use Aseprite's per-frame ms timings — collapse to average # fps for the Animation; per-frame durations would need a # variable-rate Animation we don't ship yet. avg_ms = frame_names.map { |n| duration(n) }.sum / frame_names.size.to_f fps = 1000.0 / avg_ms if avg_ms > 0 end Animation.new(self, frames: rects, fps: fps || 12, loop: loop) end |
#duration(name) ⇒ Object
Integer milliseconds per frame, as exported by Aseprite. Returns 0 if the source didn't include durations (TexturePacker etc.).
89 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 89 def duration(name) = @durations[_normalize(name)] || 0 |
#frame_names ⇒ Object
Returns the frame names.
54 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 54 def frame_names = @regions.keys |
#region(name) ⇒ SFML::Rect
Returns the pixel rect for frame name.
58 59 60 61 62 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 58 def region(name) @regions[_normalize(name)] or raise LoadError, "TextureAtlas: no frame named #{name.inspect} " \ "(have: #{@regions.keys.first(5).inspect}...)" end |
#regions ⇒ Object
The internal frame-name → Rect hash. Useful for filtering:
walk_frames = atlas.regions.select { |k, _| k.start_with?("walk-") }
94 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 94 def regions = @regions |
#sprite(name, **opts) ⇒ Object
Build a fresh Sprite bound to the atlas texture with its texture_rect set to this frame.
66 67 68 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 66 def sprite(name, **opts) Sprite.new(@texture, **opts).tap { |s| s.texture_rect = region(name) } end |
#to_s ⇒ Object Also known as: inspect
String representation for debugging.
97 |
# File 'lib/sfml/graphics/texture_atlas.rb', line 97 def to_s = "#<TextureAtlas #{@regions.size} frames#{@source ? " from #{File.basename(@source)}" : ""}>" |