def tileset2resources(tileset, basedir, projroot, outdir): tile_width = int(tileset.getAttribute('tilewidth')) tile_height = int(tileset.getAttribute('tileheight')) tile_spacing = int(util.attr(tileset, 'spacing', 0)) margin = int(util.attr(tileset, 'margin', 0)) image = tileset.getElementsByTagName('image')[0] image_rel_name = image.getAttribute('source') _, image_name = os.path.split(image_rel_name) shutil.copyfile(os.path.join(basedir, image_rel_name), os.path.join(outdir, image_name)) image_name, _ = os.path.splitext(image_name) base_outname = os.path.join(outdir, image_name) dat_outname = '%s.dat' % base_outname order_outname = '%s.order' % base_outname img_width = int(image.getAttribute('width')) img_height = int(image.getAttribute('height')) width_in_tiles = int(round((img_width - 2*margin) / (tile_width))) height_in_tiles = int(round((img_height - 2*margin) / (tile_height))) # grab terrain properties. these will be the defaults for tile # properties terrain_properties = {} terraintypes = tileset.getElementsByTagName('terraintypes') if terraintypes: terrains = terraintypes[0].getElementsByTagName('terrain') for ii in range(len(terrains)): tprops = {} terrain_properties[ii] = tprops terrain = terrains[ii] properties = terrain.getElementsByTagName('properties') if properties: for prop in properties[0].getElementsByTagName('property'): tprops[prop.getAttribute('name')] = prop.getAttribute('value') # grab any tile properties that exist tile_properties = {} for tile in tileset.getElementsByTagName('tile'): tid = int(tile.getAttribute('id')) props = {} tile_properties[tid] = props # first grab the inherited terrain properties terrain = tile.getAttribute('terrain') or '' for terrain_id in terrain.split(','): props.update(terrain_properties[int(terrain_id)]) # now merge in the tile specific properties properties = tile.getElementsByTagName('properties') if not properties: continue for prop in properties[0].getElementsByTagName('property'): props[prop.getAttribute('name')] = prop.getAttribute('value') nentries = width_in_tiles * height_in_tiles with open(dat_outname, "wb") as outdat: util.write_short(outdat, nentries) for tnum in range(nentries): row = int(tnum / width_in_tiles) col = tnum % width_in_tiles # compute the margin impact xpad = margin + col * tile_spacing ypad = margin + row * tile_spacing xstart = xpad + col * tile_width ystart = ypad + row * tile_height xend = xstart + tile_width yend = ystart + tile_height u0 = float(xstart) / img_width v1 = float(ystart) / img_height u1 = float(xend) / img_width v0 = float(yend) / img_height parms = (tile_width, tile_height, u0, v0, u1, v1, "%d" % tnum) #print(row, col, (xstart, ystart, xend, yend), parms) outdat.write(util.pack_sprite(*parms)) with open(order_outname, "w") as outnames: for ii in range(nentries): outnames.write("%d\n" % ii) # revise base_outname such that it's relative to what we hope to # the project root base_outname = os.path.relpath(base_outname, projroot) return (base_outname, nentries, tile_properties)
def mk_sheet(filenames, outbase, tgt_dims, trim, sort, system): print tgt_dims outimagename = outbase + '.png' outdatname = outbase + '.dat' outdat = open(outdatname, 'wb') tgt_w, tgt_h = tgt_dims tgt = Image.new("RGBA", tgt_dims) metadata = [] current_x = 0 current_y = 0 pad = 1 max_row_h = 0 nentries = len(filenames) * 2 # for flips util.write_short(outdat, nentries) if sort: # sort by height print 'sorting tiles for more efficient packing' objects = [] for fname in filenames: img = Image.open(fname) img_w, img_h = img.size objects.append({'fname': fname, 'height': img_h}) objects.sort(key=lambda x: x['height']) filenames = [ obj['fname'] for obj in objects ] else: print 'not sorting tiles' def system_for_file(fname): path, basename = os.path.split(fname) base, ext = os.path.splitext(basename) base, p, sys = base.partition('@') if p: return (os.path.join(path, base) + ext, sys) else: return fname, None # if we got a system override command then remove all # basefilenames that have an override overrides = [] for fname in filenames: base, sys = system_for_file(fname) if system and sys == system: overrides.append(base) # filter the filenames temp = [] for fname in filenames: if not (fname in overrides): temp.append(fname) filenames = temp for fname in filenames: img = Image.open(fname) fname, sys = system_for_file(fname) junk, basename = os.path.split(fname) if sys and sys != system: continue # skip if basename in trim: img = img.crop(find_visible_bounds(img)) img_w, img_h = img.size def state_str(): return '"%s" (%d, %d)' % (fname, img_w, img_h) if current_x + img_w > tgt_w: if max_row_h == 0: raise Exception('%s: nothing fits' % state_str()) current_y += max_row_h + pad current_x = 0 max_row_h = 0 if current_y + img_h > tgt_h: raise Exception('%s: out of vertical space' % state_str()) max_row_h = max(max_row_h, img_h) # finally, insert the image tgt.paste(img, (current_x, current_y)) u0 = float(current_x) / tgt_w v1 = float(current_y) / tgt_h u1 = float(current_x + img_w) / tgt_w v0 = float(current_y + img_h) / tgt_h pakname, _ = os.path.splitext(basename) struct_tuple = (img_w, img_h, u0, v0, u1, v1, pakname) outdat.write(util.pack_sprite(*struct_tuple)) # flipped in the x direction struct_tuple = (img_w, img_h, u1, v0, u0, v1, "/x" + pakname) outdat.write(util.pack_sprite(*struct_tuple)) current_x += img_w + pad tgt.save(outimagename) outdat.close() print "%d entries" % nentries