Class: Pixelart::SpritesheetEx

Inherits:
Object
  • Object
show all
Defined in:
lib/punks/pixelart/spritesheet.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(img, recs, width: 24, height: 24) ⇒ SpritesheetEx

Returns a new instance of SpritesheetEx.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/punks/pixelart/spritesheet.rb', line 150

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



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/punks/pixelart/spritesheet.rb', line 92

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'] )
            gender     = normalize_gender( rec['gender'] )
            size       = normalize_size( rec['size'] )
            type       = rec['type']

            more_names = (rec['more_names'] || '').split( '|' )
            more_names = more_names.map {|str| normalize_name( str ) }

            Metadata::SpriteEx.new(
              id:         id,
              name:       name,
              type:       type,
              gender:     gender,
              size:       size,
              more_names: more_names )
          end
   recs
end

.normalize_gender(str) ⇒ Object



66
67
68
69
70
71
# File 'lib/punks/pixelart/spritesheet.rb', line 66

def self.normalize_gender( str )
   ## e.g. Female => f
   ##      F => f
   ##  always return f/m
   str.downcase[0]
end

.normalize_key(str) ⇒ Object

static helpers - (turn into “true” static self.class methods - why? why not?)



61
62
63
64
# File 'lib/punks/pixelart/spritesheet.rb', line 61

def self.normalize_key( str )
  ## add & e.g. B&W
   str.downcase.gsub(/[ ()&°_-]/, '').strip
end

.normalize_name(str) ⇒ Object



81
82
83
84
# File 'lib/punks/pixelart/spritesheet.rb', line 81

def self.normalize_name( str )
  ## normalize spaces in more names
  str.strip.gsub( /[ ]{2,}/, ' ' )
end

.normalize_size(str) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/punks/pixelart/spritesheet.rb', line 73

def self.normalize_size( str )
   ## e.g. U or Unisize or Univeral => u
   ##      S or Small               => s
   ##      L or Large               => l
   ##   always return u/l/s
   str.downcase[0]
end

.read(image_path = "./spritesheet.png", meta_path = "./spritesheet.csv", width: 24, height: 24) ⇒ Object



138
139
140
141
142
143
144
145
146
# File 'lib/punks/pixelart/spritesheet.rb', line 138

def self.read( image_path="./spritesheet.png",
               meta_path="./spritesheet.csv",
                 width: 24,
                 height: 24)
  img = ImageComposite.read( image_path, width: width, height: height )
  recs = read_records( meta_path )

  new( img, recs, width: width, height: height )
end

.read_records(path) ⇒ Object Also known as: read_meta

method _build_recs



130
131
132
133
# File 'lib/punks/pixelart/spritesheet.rb', line 130

def self.read_records( path )
   recs = CsvHash.read( path )
   _build_recs( recs )
end

Instance Method Details

#_build_attributes_by_name(recs) ⇒ Object

helpers



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/punks/pixelart/spritesheet.rb', line 256

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 )
      key << "_(#{rec.gender}+#{rec.size})"  if rec.attribute?

      if h[ key ]
        puts "!!! ERROR - attribute with key >#{key}< is not unique:"
        pp rec
        puts "duplicate:"
        pp h[key]
        exit 1
      end
      h[ key ] = rec
    end
 end
  ## pp h
  h
end

#find_by(name:, gender: nil, size: nil, style: nil, warn: true) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/punks/pixelart/spritesheet.rb', line 241

def find_by( name:,
             gender: nil,
             size: nil,
             style: nil,
             warn: true )  ## gender (m/f) required for attributes!!!
   rec = find_meta_by( name: name,
                       gender: gender, size: size, style: style,
                       warn: warn )

   ## return image if record found
   rec ? @image[ rec.id ] : nil
end

#find_meta_by(name:, gender: nil, size: nil, style: nil, warn: true) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/punks/pixelart/spritesheet.rb', line 174

def find_meta_by( name:,
                  gender: nil,
                  size: nil,
                  style: nil,
                  warn: true )   ## note: gender (m/f) required for attributes!!!

   key = normalize_key( name )  ## normalize name q(uery) string/symbol

   keys = []    ## note allow lookup by more than one keys
                   ##  e.g. if gender set try   f/m first and than try unisex as fallback
   if gender
      gender = normalize_gender( gender )
      ## auto-fill size if not passed in
      ##    for f(emale)  =>   s(mall)
      ##        m(ale)    =>   l(arge)
      size =  if size.nil?
                gender == 'f' ? 's' : 'l'
              else
                normalize_size( size )
              end

      ###
      #  try (auto-add) style-specific version first (fallback to "regular" if not found)
      if style
        ## for now only support natural series
        style_key =  if style.downcase.start_with?( 'natural' )
                         'natural'
                     else
                       puts "!! ERROR - unknown attribute style #{style}; sorry"
                       exit 1
                     end

        keys << "#{key}#{style_key}_(#{gender}+#{size})"
        ## auto-add (u)niversal size as fallback
        keys << "#{key}#{style_key}_(#{gender}+u)"  if size == 's' || size == 'l'
        ## auto-add u(nisex) as fallback
        keys << "#{key}#{style_key}_(u+#{size})"    if gender == 'f' || gender == 'm'
      end


      keys << "#{key}_(#{gender}+#{size})"
      ## auto-add (u)niversal size as fallback
      keys << "#{key}_(#{gender}+u)"  if size == 's' || size == 'l'
      ## auto-add u(nisex) as fallback
      keys << "#{key}_(u+#{size})"    if gender == 'f' || gender == 'm'
   else
      keys << key
   end


   rec = nil
   keys.each do |key|
      rec = @attributes_by_name[ key ]
      if rec
        puts " lookup #{@image.tile_width}x#{@image.tile_height} >#{key}< => #{rec.id}: #{rec.name} / #{rec.type} (#{rec.gender}+#{rec.size})"
        # pp rec
        break
      end
   end

   if warn && rec.nil?
      puts "!! WARN - no lookup #{@image.tile_width}x#{@image.tile_height} found for #{keys.size} key(s) >#{keys.inspect}<"
   end

   rec
end

#imageObject Also known as: composite



167
# File 'lib/punks/pixelart/spritesheet.rb', line 167

def image() @image; end

#normalize_gender(str) ⇒ Object



87
# File 'lib/punks/pixelart/spritesheet.rb', line 87

def normalize_gender( str )  self.class.normalize_gender( str ); end

#normalize_key(str) ⇒ Object



86
# File 'lib/punks/pixelart/spritesheet.rb', line 86

def normalize_key( str )     self.class.normalize_key( str ); end

#normalize_name(str) ⇒ Object



89
# File 'lib/punks/pixelart/spritesheet.rb', line 89

def normalize_name( str )    self.class.normalize_name( str ); end

#normalize_size(str) ⇒ Object



88
# File 'lib/punks/pixelart/spritesheet.rb', line 88

def normalize_size( str )    self.class.normalize_size( str ); end

#recordsObject Also known as: meta



170
# File 'lib/punks/pixelart/spritesheet.rb', line 170

def records() @recs; end