Class: Zif::Services::SpriteRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/zif/services/sprite_registry.rb

Overview

This service is for registering your sprite assets once, and assists in creating new Zif::Sprite instances from the parameters described when registering.

Examples:

Creating 20 copies of a basic sprite

$services[:sprite_registry].register_basic_sprite(:dragon_1, width: 82, height: 66)
my_dragons = 20.times.map { $services[:sprite_registry].construct(:dragon_1) }
# Every dragon in the above array will have path, w, h, source_w, source_h all set to sensible defaults.

Creating 20 copies of a customized sprite

# Starting from above
giant_dragon_prototype = $services[:sprite_registry].construct(:dragon_1)
giant_dragon_prototype.w = giant_dragon_prototype.w * 10
giant_dragon_prototype.h = giant_dragon_prototype.h * 10

$services[:sprite_registry].add_sprite(:giant_dragon, my_giant_dragon)
my_giant_dragons = 20.times.map { $services[:sprite_registry].construct(:giant_dragon) }

# We've just added another sprite we can create by name.  :dragon_1 is still there if we want the basic version.

Instance Attribute Summary collapse

1. Public Interface collapse

2. Private-ish methods collapse

Constructor Details

#initializeSpriteRegistry




28
29
30
# File 'lib/zif/services/sprite_registry.rb', line 28

def initialize
  reset_registry
end

Instance Attribute Details

#registryHash<(Symbol, String), Zif::Sprite> (readonly)

Returns The registry of your sprites.

Returns:

  • (Hash<(Symbol, String), Zif::Sprite>)

    The registry of your sprites



23
24
25
# File 'lib/zif/services/sprite_registry.rb', line 23

def registry
  @registry
end

Instance Method Details

#add_sprite(name, sprite) ⇒ Object

Add an already created sprite object to the registry

Parameters:

  • name (Symbol, String)

    The name of your sprite, used with #construct.

  • sprite (Zif::Sprite, Object)

    The sprite object to register.



40
41
42
# File 'lib/zif/services/sprite_registry.rb', line 40

def add_sprite(name, sprite)
  @registry[name] = sprite
end

#alias_sprite(name, alias_to) ⇒ Object

Parameters:

  • name (Symbol, String)

    The name of an existing entry in the registry

  • alias_to (Symbol, String)

    Another name to use for this sprite, with #construct



52
53
54
55
56
57
58
# File 'lib/zif/services/sprite_registry.rb', line 52

def alias_sprite(name, alias_to)
  raise "SpriteRegistry: No sprite named #{name.inspect} in the registry" unless @registry[name]

  # puts "SpriteRegistry#alias_sprite: #{alias_to} is now an alias for #{name}"

  @registry[alias_to] = @registry[name]
end

#autotile_name_from_bits(bits) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/zif/services/sprite_registry.rb', line 200

def autotile_name_from_bits(bits)
  direction_name = ''
  direction_name += '_north' if (bits & 1).positive?
  direction_name += '_east'  if (bits & 2).positive?
  direction_name += '_south' if (bits & 4).positive?
  direction_name += '_west'  if (bits & 8).positive?
  direction_name += '_ne'    if (bits & 16).positive?
  direction_name += '_se'    if (bits & 32).positive?
  direction_name += '_sw'    if (bits & 64).positive?
  direction_name += '_nw'    if (bits & 128).positive?

  direction_name
end

#construct(name) ⇒ Zif::Sprite, Object

Create a new copy of a sprite which has been previously registered, using #dup

Parameters:

  • name (Symbol, String)

    The name of an existing entry in the registry

Returns:



189
190
191
192
193
194
# File 'lib/zif/services/sprite_registry.rb', line 189

def construct(name)
  raise "SpriteRegistry: No sprite named #{name.inspect} in the registry" unless @registry[name]
  raise "Invalid sprite in registry: #{name.inspect}" unless @registry[name].respond_to?(:dup)

  @registry[name].dup
end

#register_autotiles(name, width:, height:, edges: 48, &block) ⇒ Object

Some background on autotiling (note the author uses a different numbering scheme - NEWS instead of NESW) gamedevelopment.tutsplus.com/tutorials/cms-25673

This method will automatically register all of the tiles for autotiling with BitmaskedTiledLayer. It’ll register every possible direction, aliasing the ones that don’t actually exist to the ones that do, depending on the number of edges specified (16 for cardinal directions only, 48 for inside corners, or 256 for every possibility). This expects that the actual filenames are using cardinal directions & diagonal directions, separated by underscores, in the following order:

_north _east _south _west _ne _se _sw _nw

It will also alias these to the raw bitmask value.

Let’s work through an example so this is clearer. You are using a 48-tile set, so you have two different versions of the tile that has an adjacent tile to the north and east, either the corner is cut or not. The one where the corner is not cut - the only adjacent tiles are north, northeast and east - looks like |_ You need to have the file for this at “sprites/name_north_east_ne.png” From that one file, it will generate the following aliases:

  • name_north_east_ne (the actual sprite)

  • All of the corner cases that don’t actually exist because this is just the 48-set and not the full 256 name_north_east_ne_se, name_north_east_ne_sw, name_north_east_ne_nw, name_north_east_ne_se_sw, …

  • Both of the above, but using the raw bitmask integer instead of the cardinal directions: 1+2+16= name_19, 1+2+16+32= name_51, …

rubocop:disable Metrics/PerceivedComplexity

Parameters:

  • name (Symbol, String)

    The prefix name of your autotiles, used with #construct, and the relative path.

  • width (Integer)

    The width of a tile. Used for w and source_w

  • height (Integer)

    The height of a tile. Used for h and source_h

  • edges (Integer) (defaults to: 48)

    The type of autotiling you are doing, must be 16, 48 or 256 16 for cardinal directions only 48 for inside corners 256 for every possibility

  • block (Proc)

    Passed to each #register_basic_sprite constructor to set @on_mouse_down on each sprite.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/zif/services/sprite_registry.rb', line 134

def register_autotiles(name, width:, height:, edges: 48, &block)
  # No edges:
  register_basic_sprite(name.to_sym, width: width, height: height, &block)
  alias_sprite(name.to_sym, "#{name}_0".to_sym)

  aliases_to_create = []
  1.upto 255 do |i|
    north = (i & 1).positive?
    east  = (i & 2).positive?
    south = (i & 4).positive?
    west  = (i & 8).positive?
    ne    = (i & 16).positive?
    se    = (i & 32).positive?
    sw    = (i & 64).positive?
    nw    = (i & 128).positive?

    cur_tile_name   = "#{name}#{autotile_name_from_bits(i)}".to_sym
    actual_i        = nil

    case edges
    when 16
      actual_i = i & 31
    when 48
      actual_i = i
      actual_i -= 16  if ne && (!north || !east)
      actual_i -= 32  if se && (!south || !east)
      actual_i -= 64  if sw && (!south || !west)
      actual_i -= 128 if nw && (!north || !west)
    else
      actual_i = i
    end

    actual_tile_name = "#{name}#{autotile_name_from_bits(actual_i)}".to_sym
    # puts "#{i} -> #{actual_i}: #{cur_tile_name} -> #{actual_tile_name}"

    bits_alias = "#{name}_#{i}".to_sym

    if actual_i == i
      register_basic_sprite(cur_tile_name, width: width, height: height, &block)
      alias_sprite(cur_tile_name, bits_alias)
    else
      aliases_to_create << [cur_tile_name, bits_alias, actual_tile_name]
    end
  end

  aliases_to_create.each do |(cur_tile_name, bits_alias, alias_tile_from)|
    alias_sprite(alias_tile_from, cur_tile_name)
    alias_sprite(alias_tile_from, bits_alias)
  end
end

#register_basic_sprite(name, width:, height:, &block) ⇒ Object

Creates a new Zif::Sprite which by convention is named the same as it’s path, in “app/sprites/<name>.png” You can, of course, modify the prototype after creation

Examples:

Registering a basic sprite in some nested location within app/sprites

# The sprite image is at "app/sprites/assets/from_dragonrubygtk/the_ones_i_like_the_best/dragon_1.png"
$services[:sprite_registry].register_basic_sprite(
  "assets/from_dragonrubygtk/the_ones_i_like_the_best/dragon_1",
  width: 82,
  height: 66
 )
$services[:sprite_registry].alias_sprite(
  "assets/from_dragonrubygtk/the_ones_i_like_the_best/dragon_1",
  :dragon_1
)
# Now you can construct(:dragon_1) but it still has the very long path

Parameters:

  • name (Symbol, String)

    The name of your sprite, used with #construct, and the relative path.

  • width (Integer)

    The width of the sprite. Used for w and source_w

  • height (Integer)

    The height of the sprite. Used for h and source_h



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/zif/services/sprite_registry.rb', line 77

def register_basic_sprite(name, width:, height:, &block)
  sprite = Zif::Sprite.new(name)
  sprite.assign(
    {
      w:        width,
      h:        height,
      path:     "sprites/#{name}.png",
      angle:    0,
      a:        255,
      r:        255,
      g:        255,
      b:        255,
      source_x: 0,
      source_y: 0,
      source_w: width,
      source_h: height
    }
  )

  sprite.on_mouse_up = block if block_given?

  add_sprite(name, sprite)
end

#reset_registryObject

Clears #registry



33
34
35
# File 'lib/zif/services/sprite_registry.rb', line 33

def reset_registry
  @registry = {}
end

#sprite_registered?(name) ⇒ Boolean

Returns Does the registry have a sprite object with this name?.

Parameters:

  • name (Symbol, String)

    The name of the sprite to check for.

Returns:

  • (Boolean)

    Does the registry have a sprite object with this name?



46
47
48
# File 'lib/zif/services/sprite_registry.rb', line 46

def sprite_registered?(name)
  @registry.key?(name)
end