Class: Pixelart::Spritesheet
- Inherits:
-
Object
- Object
- Pixelart::Spritesheet
- Defined in:
- lib/spritesheet/packer.rb,
lib/spritesheet/spritesheet.rb
Class Method Summary collapse
-
._build_recs(recs) ⇒ Object
build and normalize (meta data) records.
-
.normalize_key(str) ⇒ Object
static helpers - (turn into "true" static self.class methods - why? why not?).
- .normalize_name(str) ⇒ Object
- .pack(path, cols: 10, dir: '.', width: 24, height: 24) ⇒ Object
- .read(image_path = "./spritesheet.png", meta_path = "./spritesheet.csv", width: 24, height: 24) ⇒ Object
-
.read_records(path) ⇒ Object
(also: read_meta)
method build_recs.
Instance Method Summary collapse
-
#_build_attributes_by_name(recs) ⇒ Object
helpers.
- #_find(name) ⇒ Object (also: #[])
- #export(path = './spritesheet.csv', format: 'csv') ⇒ Object
- #find_by(name:, warn: true) ⇒ Object
- #find_meta_by(name:, warn: true) ⇒ Object
- #image ⇒ Object (also: #composite)
-
#initialize(img, recs, width: 24, height: 24) ⇒ Spritesheet
constructor
A new instance of Spritesheet.
- #normalize_key(str) ⇒ Object
- #normalize_name(str) ⇒ Object
- #records ⇒ Object (also: #meta)
Constructor Details
#initialize(img, recs, width: 24, height: 24) ⇒ Spritesheet
Returns a new instance of Spritesheet.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/spritesheet/spritesheet.rb', line 99 def initialize( img, recs, width: 24, height: 24 ) @width = width @height = height ## todo: check if img is a ImageComposite or plain Image? ## if plain Image "auto-wrap" into ImageComposite - why? why not? @image = img @recs = recs ## lookup by "case/space-insensitive" name / key @attributes_by_name = _build_attributes_by_name( @recs ) end |
Class Method Details
._build_recs(recs) ⇒ Object
build and normalize (meta data) records
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/spritesheet/spritesheet.rb', line 43 def self._build_recs( recs ) ## build and normalize (meta data) records ## sort by id recs = recs.sort do |l,r| l['id'].to_i( 10 ) <=> r['id'].to_i( 10 ) # use base10 (decimal) end ## assert all recs are in order by id (0 to size) recs.each_with_index do |rec, exp_id| id = rec['id'].to_i(10) if id != exp_id puts "!! ERROR - meta data record ids out-of-order - expected id #{exp_id}; got #{id}" exit 1 end end ## convert to "wrapped / immutable" kind-of struct recs = recs.map do |rec| id = rec['id'].to_i( 10 ) name = normalize_name( rec['name'] ) ## todo: double check if rec['type'] returns nil or empty string if column/field not present? type = rec['type'] || rec['category'] more_names = (rec['more_names'] || '').split( '|' ) more_names = more_names.map {|str| normalize_name( str ) } Metadata::Sprite.new( id: id, name: name, type: type, more_names: more_names ) end recs end |
.normalize_key(str) ⇒ Object
static helpers - (turn into "true" static self.class methods - why? why not?)
26 27 28 29 30 |
# File 'lib/spritesheet/spritesheet.rb', line 26 def self.normalize_key( str ) ## add & e.g. B&W ## add ' e.g. McDonald's Red str.downcase.gsub(/[ ()&°'_-]/, '').strip end |
.normalize_name(str) ⇒ Object
32 33 34 35 |
# File 'lib/spritesheet/spritesheet.rb', line 32 def self.normalize_name( str ) ## normalize spaces in more names str.strip.gsub( /[ ]{2,}/, ' ' ) end |
.pack(path, cols: 10, dir: '.', width: 24, height: 24) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/spritesheet/packer.rb', line 7 def self.pack( path, cols: 10, dir: '.', width: 24, height: 24 ) ## check - change dir to image_dir or such - why? why not? attributes = CsvHash.read( path ) puts " #{attributes.size} record(s)" #=> ?? total = attributes.size rows = total/cols rows += 1 if (total % cols) != 0 ## add extra row for remainder sheet = ImageComposite.new( cols, rows, width: width, height: height ) = [] ## output meta(data) records #### # add attributes attributes.each do |rec| img_path = rec['path'] sheet << Image.read( "#{dir}/#{img_path}" ) name = rec['name'] more_names = (rec['more_names'] || '').split( '|' ) if name.nil? || name.empty? name = File.basename( img_path, File.extname( img_path )) end ## normalize spaces in more names names = [name] + more_names names = names.map {|str| str.strip.gsub(/[ ]{2,}/, ' ' )} << { 'id' => .size.to_s, ## note: always strings expected (NOT integer numbers) 'category' => rec['type'] || rec['category'], 'name' => names[0], 'more_names' => names[1..-1].join( ' | ')} end ## pp meta ## puts " #{meta.size} record(s)" new( sheet, _build_recs( ), width: width, height: height ) end |
.read(image_path = "./spritesheet.png", meta_path = "./spritesheet.csv", width: 24, height: 24) ⇒ Object
87 88 89 90 91 92 93 94 95 |
# File 'lib/spritesheet/spritesheet.rb', line 87 def self.read( image_path="./spritesheet.png", ="./spritesheet.csv", width: 24, height: 24) img = ImageComposite.read( image_path, width: width, height: height ) recs = read_records( ) new( img, recs, width: width, height: height ) end |
.read_records(path) ⇒ Object Also known as: read_meta
method build_recs
78 79 80 81 |
# File 'lib/spritesheet/spritesheet.rb', line 78 def self.read_records( path ) recs = CsvHash.read( path ) _build_recs( recs ) end |
Instance Method Details
#_build_attributes_by_name(recs) ⇒ Object
helpers
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/spritesheet/spritesheet.rb', line 149 def _build_attributes_by_name( recs ) h = {} recs.each_with_index do |rec| names = [rec.name] + rec.more_names names.each do |name| key = normalize_key( name ) if h[ key ] puts "!!! ERROR - attribute name is not unique:" pp rec puts "duplicate:" pp h[key] exit 1 end h[ key ] = rec end end ## pp h h end |
#_find(name) ⇒ Object Also known as: []
143 |
# File 'lib/spritesheet/spritesheet.rb', line 143 def _find( name ) find_by( name: name, warn: false ); end |
#export(path = './spritesheet.csv', format: 'csv') ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/spritesheet/packer.rb', line 64 def export( path='./spritesheet.csv', format: 'csv' ) if format.downcase.to_s == 'csv' headers = ['id', 'category', 'name', 'more_names'] ## todo/fix: make sure dirname path exists!!! File.open( path, "w:utf-8" ) do |f| f.write( headers.join( ', ')) f.write( "\n") records.each do |rec| values = [rec.id, rec.type, rec.name, rec.more_names.join( ' | ')] f.write( values.join( ', ' )) f.write( "\n" ) end end else puts "!! ERROR - unsupported export format >#{format}<; sorry" exit 1 end end |
#find_by(name:, warn: true) ⇒ Object
136 137 138 139 140 141 |
# File 'lib/spritesheet/spritesheet.rb', line 136 def find_by( name:, warn: true ) rec = ( name: name, warn: warn ) ## return (cropped/sliced) image from image composite if record found rec ? @image[ rec.id ] : nil end |
#find_meta_by(name:, warn: true) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/spritesheet/spritesheet.rb', line 123 def ( name:, warn: true ) key = normalize_key( name ) ## normalize q(uery) string/symbol rec = @attributes_by_name[ key ] if rec puts " lookup >#{key}< => #{rec.id}: #{rec.name} / #{rec.type}" else puts "!! WARN - no lookup found for key >#{key}<" if warn end rec end |
#image ⇒ Object Also known as: composite
116 |
# File 'lib/spritesheet/spritesheet.rb', line 116 def image() @image; end |
#normalize_key(str) ⇒ Object
37 |
# File 'lib/spritesheet/spritesheet.rb', line 37 def normalize_key( str ) self.class.normalize_key( str ); end |
#normalize_name(str) ⇒ Object
38 |
# File 'lib/spritesheet/spritesheet.rb', line 38 def normalize_name( str ) self.class.normalize_name( str ); end |
#records ⇒ Object Also known as: meta
119 |
# File 'lib/spritesheet/spritesheet.rb', line 119 def records() @recs; end |