Class: SFML::SpriteSheet

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/graphics/sprite_sheet.rb

Overview

A grid-based slice of a texture. Where TextureAtlas loads an already-packed sheet with named frames, SpriteSheet slices a uniformly-gridded image into numbered frames at load time.

Use a SpriteSheet when your art is a regular grid (run cycles baked at 32×32 cells); use a TextureAtlas when frames are densely packed at irregular sizes.

sheet = SFML::SpriteSheet.load("hero.png", frame_size: [32, 32])

sheet.frame_count       # 8 if the image is 256×32
sheet.region(0)         # SFML::Rect of the first cell
sheet.sprite(0)         # ready-to-draw SFML::Sprite of the first cell

frame_size can be a [w, h] pair (one number for both if frame_size: 32). padding and margin let you skip pixels between cells and around the edge respectively — common when the source image has separators or a 1px outline to prevent bleed.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(texture:, frame_size:, padding: 0, margin: 0) ⇒ SpriteSheet



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/sfml/graphics/sprite_sheet.rb', line 28

def initialize(texture:, frame_size:, padding: 0, margin: 0)
  @texture = texture
  fw, fh = _pair(frame_size)
  pw, ph = _pair(padding)
  mw, mh = _pair(margin)

  tex_w, tex_h = texture.size.x, texture.size.y
  @cols = (tex_w - 2 * mw + pw) / (fw + pw)
  @rows = (tex_h - 2 * mh + ph) / (fh + ph)
  @frame_w, @frame_h = fw, fh

  # Pre-compute every rect once. Cheap (a few hundred at most),
  # and #region becomes a flat array lookup.
  @regions = Array.new(@cols * @rows) do |i|
    col = i % @cols
    row = i / @cols
    x = mw + col * (fw + pw)
    y = mh + row * (fh + ph)
    Rect.new([x, y], [fw, fh])
  end.freeze
end

Instance Attribute Details

#cols ⇒ Object (readonly)

The texture, cols, rows, frame w, frame h components.



51
52
53
# File 'lib/sfml/graphics/sprite_sheet.rb', line 51

def cols
  @cols
end

#frame_h ⇒ Object (readonly)

The texture, cols, rows, frame w, frame h components.



51
52
53
# File 'lib/sfml/graphics/sprite_sheet.rb', line 51

def frame_h
  @frame_h
end

#frame_w ⇒ Object (readonly)

The texture, cols, rows, frame w, frame h components.



51
52
53
# File 'lib/sfml/graphics/sprite_sheet.rb', line 51

def frame_w
  @frame_w
end

#rows ⇒ Object (readonly)

The texture, cols, rows, frame w, frame h components.



51
52
53
# File 'lib/sfml/graphics/sprite_sheet.rb', line 51

def rows
  @rows
end

#texture ⇒ Object (readonly)

The texture, cols, rows, frame w, frame h components.



51
52
53
# File 'lib/sfml/graphics/sprite_sheet.rb', line 51

def texture
  @texture
end

Class Method Details

.load(path, frame_size:, padding: 0, margin: 0, smooth: true) ⇒ Object

Returns the self.



23
24
25
26
# File 'lib/sfml/graphics/sprite_sheet.rb', line 23

def self.load(path, frame_size:, padding: 0, margin: 0, smooth: true)
  new(texture: Texture.load(path, smooth: smooth),
      frame_size: frame_size, padding: padding, margin: margin)
end

Instance Method Details

#animation(frame_indexes: nil, fps: 12, loop: true) ⇒ Object

An Animation looping through frame_indexes (defaults to all frames in row-major order).



78
79
80
81
82
83
84
85
86
# File 'lib/sfml/graphics/sprite_sheet.rb', line 78

def animation(frame_indexes: nil, fps: 12, loop: true)
  indexes = frame_indexes || (0...frame_count).to_a
  Animation.new(
    self,
    frames: indexes.map { |i| region(i) },
    fps:    fps,
    loop:   loop,
  )
end

#frame_count ⇒ Object

Returns the frame count.



54
# File 'lib/sfml/graphics/sprite_sheet.rb', line 54

def frame_count = @regions.size

#region(index) ⇒ Object

The pixel Rect for cell index (0 = top-left, increases row-major). Negative indexes wrap (e.g. -1 = last).



58
59
60
61
# File 'lib/sfml/graphics/sprite_sheet.rb', line 58

def region(index)
  i = Integer(index) % frame_count
  @regions[i]
end

#region_at(col, row) ⇒ Object

[col, row] accessor for callers who prefer 2D coords.

Raises:

  • (IndexError)


64
65
66
67
68
# File 'lib/sfml/graphics/sprite_sheet.rb', line 64

def region_at(col, row)
  raise IndexError, "col #{col} out of range (cols: #{@cols})" if col < 0 || col >= @cols
  raise IndexError, "row #{row} out of range (rows: #{@rows})" if row < 0 || row >= @rows
  @regions[row * @cols + col]
end

#sprite(index, **opts) ⇒ Object

Fresh Sprite pointing at cell index. Combine with #sprite= patterns or feed into SFML::Animation.



72
73
74
# File 'lib/sfml/graphics/sprite_sheet.rb', line 72

def sprite(index, **opts)
  Sprite.new(@texture, **opts).tap { |s| s.texture_rect = region(index) }
end

#to_s ⇒ Object Also known as: inspect

String representation for debugging.



89
# File 'lib/sfml/graphics/sprite_sheet.rb', line 89

def to_s = "#<SpriteSheet #{@cols}×#{@rows} (#{@frame_w}×#{@frame_h}px cells)>"