class Sabrina::Plugins::Spritesheet
This {Plugin} provides an abstraction for manipulating all {Sprite Sprites} and {Palette Palettes} associated with a {Monster}.
@see Plugin
Constants
- ENHANCES
An abstract class for dealing with further abstractions of data related to a specific, numbered monster.
See {Sabrina::Plugins} for extensions that might enhance this class with added functionality.
- FEATURES
@see Plugin::FEATURES
- PLUGIN_NAME
@see Plugin::PLUGIN_NAME
- SHORT_NAME
@see Plugin::SHORT_NAME
Attributes
The palettes used by the sprites.
@return [Array]
The sprites.
@return [Array]
Public Class Methods
Generates a new Spritesheet
object.
@return [Spritesheet]
# File lib/sabrina/plugins/spritesheet.rb, line 51 def initialize(monster) @monster = monster @rom = monster.rom @index = monster.index @palettes = [ Palette.from_table(@monster.rom, :palette_table, @monster.index), Palette.from_table(@monster.rom, :shinypal_table, @monster.index) ] @sprites = [ Sprite.from_table(@monster.rom, :front_table, @monster.index), Sprite.from_table(@monster.rom, :back_table, @monster.index) ] end
Public Instance Methods
@return [Array] @see ChildrenManager
# File lib/sabrina/plugins/spritesheet.rb, line 69 def children @sprites + @palettes end
Justify sprites to the target ROM count as per ROM {Config}, assuming 64x64 frame size.
# File lib/sabrina/plugins/spritesheet.rb, line 75 def justify @sprites.map(&:justify) end
Load data from a file.
@return [Array] Any return data from child methods.
# File lib/sabrina/plugins/spritesheet.rb, line 82 def load(file = @monster.filename, dir = @monster.work_dir, *_args) path = get_path(file, dir) a = split_canvas(ChunkyPNG::Canvas.from_file(path)) h = { rom: @rom, index: @index } normal_rgb = a[0].to_rgb_stream + a[2].to_rgb_stream shiny_rgb = a[1].to_rgb_stream + a[3].to_rgb_stream @palettes = Palette.create_synced_palettes( normal_rgb, shiny_rgb, h.merge(table: :palette_table), h.merge(table: :shinypal_table) ) frames = @rom.special_frames.fetch(@index, @rom.frames) front = crop_canvas(a[0], frames.first * 64) back = crop_canvas(a[2], frames.last * 64) @sprites = [ Sprite.from_canvas( front, @palettes.first, h.merge(table: :front_table) ), Sprite.from_canvas( back, @palettes.first, h.merge(table: :back_table) ) ] justify children end
Save data to a file.
@return [Array] Any return data from child methods.
# File lib/sabrina/plugins/spritesheet.rb, line 121 def save(file = @monster.filename, dir = @monster.work_dir, *_args) a = [] @sprites.product(@palettes).each do |x| a << x.first.to_canvas(x.last) end path = get_path(file, dir, mkdir: true) combine_canvas(a).save(path) end
Private Instance Methods
Horizontally combine a one-dimensional array of {rdoc.info/gems/chunky_png/1.2.0/ChunkyPNG/Canvas Canvas} objects into a single, wide canvas.
@param [Array] a an array of Canvas objects. @return [Canvas] the combined canvas.
# File lib/sabrina/plugins/spritesheet.rb, line 146 def combine_canvas(a) out_c = ChunkyPNG::Canvas.new(a.first.width * a.length, a.first.height) a.each_index { |i| out_c.replace!(a[i], a.first.width * i) } out_c end
Vertically combine a one-dimensional array of {rdoc.info/gems/chunky_png/1.2.0/ChunkyPNG/Canvas Canvas} objects into a single, tall canvas.
@param [Array] a an array of Canvas objects. @return [Canvas] the combined canvas.
# File lib/sabrina/plugins/spritesheet.rb, line 158 def combine_canvas_vert(a) out_c = ChunkyPNG::Canvas.new(a.first.width, a.first.height * a.length) a.each_index { |i| out_c.replace!(a[i], 0, a.first.height * i) } out_c end
Crops the canvas to the specified height if taller.
# File lib/sabrina/plugins/spritesheet.rb, line 135 def crop_canvas(c, h) return c.crop(0, 0, c.width, h) if c.height > h c end
Concatenate the file name and directory into a full path, optionally creating the directory if it doesn’t exist.
@param [String] file @param [String] dir @param [Hash] h
@option h [Boolean] :mkdir If +true+, create +dir+ if it doesn't exist.
@return [String]
# File lib/sabrina/plugins/spritesheet.rb, line 185 def get_path(file, dir, h = {}) f, d = file.dup, dir.dup d << '/' unless d.empty? || d.end_with?('/') FileUtils.mkpath(d) if h.fetch(:mkdir, false) && !Dir.exist?(d) path = d << f path << '.png' unless path.downcase.end_with?('.png') end
Split a {rdoc.info/gems/chunky_png/1.2.0/ChunkyPNG/Canvas Canvas} into an array of canvases horizontally.
@param [Canvas] c @param [Integer] w tile width. @return [Array] an array of Canvas objects.
# File lib/sabrina/plugins/spritesheet.rb, line 170 def split_canvas(c, w = 64) out_a = [] (c.width / w).times { |i| out_a << c.crop(i * w, 0, w, c.height) } out_a end