Example #1
0
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)
Example #2
0
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