|
|
@ -3,88 +3,89 @@ |
|
|
|
import glob |
|
|
|
import json |
|
|
|
import os |
|
|
|
import pprint |
|
|
|
import pygame |
|
|
|
import pprint # pylint: disable=unused-import |
|
|
|
import re |
|
|
|
import sys |
|
|
|
|
|
|
|
import pygame |
|
|
|
|
|
|
|
# The guide in tiles/guide.png is quite helpful. |
|
|
|
|
|
|
|
# TODO: sort the stuff in free/ and noncommercial/ |
|
|
|
# TODO: in future/100/characters there are some doors, conveyor belts, screens |
|
|
|
|
|
|
|
SPRITE_FILES = [ |
|
|
|
'animals/sheets/*.png', |
|
|
|
'beasttribes/100/*.png', |
|
|
|
'characters/sheets/*.png', |
|
|
|
'christmas/1x/gnome*.png', |
|
|
|
'christmas/1x/reindeer*.png', |
|
|
|
'christmas/1x/rudolph*.png', |
|
|
|
'christmas/1x/xmas*.png', |
|
|
|
'dwarvesvselves/regularsize/*.png', |
|
|
|
'future/100/characters/cars.png', |
|
|
|
'future/100/characters/future*.png', |
|
|
|
'future/100/characters/military*.png', |
|
|
|
'future/100/characters/modern*.png', |
|
|
|
'halloween/ghost1.png', |
|
|
|
'halloween/horseman/*1.png', |
|
|
|
'halloween/reaper/*1.png', |
|
|
|
'halloween/witch/1x/*.png', |
|
|
|
'lichcrusades/100/*.png', |
|
|
|
'monsters/1x/*.png', |
|
|
|
'mythicalbosses/100/*.png', |
|
|
|
'mythicalbosses/dinosaurs/*.png', |
|
|
|
'npcanimations/rpgmaker/1/*.png', |
|
|
|
'ship/100/char/airship*.png', |
|
|
|
'ship/100/char/boat*.png', |
|
|
|
'ship/100/char/pirates_100.png', |
|
|
|
'ship/100/char/ship*.png', |
|
|
|
'animals/sheets/*.png', |
|
|
|
'beasttribes/100/*.png', |
|
|
|
'characters/sheets/*.png', |
|
|
|
'christmas/1x/gnome*.png', |
|
|
|
'christmas/1x/reindeer*.png', |
|
|
|
'christmas/1x/rudolph*.png', |
|
|
|
'christmas/1x/xmas*.png', |
|
|
|
'dwarvesvselves/regularsize/*.png', |
|
|
|
'future/100/characters/cars.png', |
|
|
|
'future/100/characters/future*.png', |
|
|
|
'future/100/characters/military*.png', |
|
|
|
'future/100/characters/modern*.png', |
|
|
|
'halloween/ghost1.png', |
|
|
|
'halloween/horseman/*1.png', |
|
|
|
'halloween/reaper/*1.png', |
|
|
|
'halloween/witch/1x/*.png', |
|
|
|
'lichcrusades/100/*.png', |
|
|
|
'monsters/1x/*.png', |
|
|
|
'mythicalbosses/100/*.png', |
|
|
|
'mythicalbosses/dinosaurs/*.png', |
|
|
|
'npcanimations/rpgmaker/1/*.png', |
|
|
|
'ship/100/char/airship*.png', |
|
|
|
'ship/100/char/boat*.png', |
|
|
|
'ship/100/char/pirates_100.png', |
|
|
|
'ship/100/char/ship*.png', |
|
|
|
] |
|
|
|
|
|
|
|
SPRITE_SIDEVIEW_FILES = [ |
|
|
|
'beasttribes/100/sv_battler/*.png', |
|
|
|
'future/100/svbattler/*.png', |
|
|
|
# TODO: these need to get scaled down 2x before they can be used. |
|
|
|
'sv_battle/RMMV/sv_actors/*.png', |
|
|
|
'beasttribes/100/sv_battler/*.png', |
|
|
|
'future/100/svbattler/*.png', |
|
|
|
# TODO: these need to get scaled down 2x before they can be used. |
|
|
|
'sv_battle/RMMV/sv_actors/*.png', |
|
|
|
] |
|
|
|
|
|
|
|
TILESET_FILES = [ |
|
|
|
'ashlands/ashlands_tileset.png', |
|
|
|
'atlantis/tf_atlantis_tiles.png', |
|
|
|
'beach/beach_tileset.png', |
|
|
|
'christmas/1x/addon_igloo_1.png', |
|
|
|
'christmas/1x/christmas*.png', |
|
|
|
'cloud/cloud_tileset.png', |
|
|
|
'darkdimension/tf_darkdimension_sheet.png', |
|
|
|
'farmandfort/ff_master_tile_sheet.png', |
|
|
|
'future/100/tilesets/*.png', |
|
|
|
'gianttree/tf_gianttree_tiles.png', |
|
|
|
'halloween/tiles/*1.png', |
|
|
|
'jungle/tf_jungle_tileset.png', |
|
|
|
'patron/train_sheet_1.png', |
|
|
|
'ruindungeons/ruindungeons_sheet_full.png', |
|
|
|
'ship/ship_big_tileset.png', |
|
|
|
'tiles/TILESETS/*.png', |
|
|
|
'winter/tiles/*.png', |
|
|
|
'ashlands/ashlands_tileset.png', |
|
|
|
'atlantis/tf_atlantis_tiles.png', |
|
|
|
'beach/beach_tileset.png', |
|
|
|
'christmas/1x/addon_igloo_1.png', |
|
|
|
'christmas/1x/christmas*.png', |
|
|
|
'cloud/cloud_tileset.png', |
|
|
|
'darkdimension/tf_darkdimension_sheet.png', |
|
|
|
'farmandfort/ff_master_tile_sheet.png', |
|
|
|
'future/100/tilesets/*.png', |
|
|
|
'gianttree/tf_gianttree_tiles.png', |
|
|
|
'halloween/tiles/*1.png', |
|
|
|
'jungle/tf_jungle_tileset.png', |
|
|
|
'patron/train_sheet_1.png', |
|
|
|
'ruindungeons/ruindungeons_sheet_full.png', |
|
|
|
'ship/ship_big_tileset.png', |
|
|
|
'tiles/TILESETS/*.png', |
|
|
|
'winter/tiles/*.png', |
|
|
|
] |
|
|
|
|
|
|
|
ANIMATION_FILES = [ |
|
|
|
'patron/fireworks*_1.png', |
|
|
|
'pixelanimations/animationsheets/*.png', |
|
|
|
'ship/100/char/!$ship_wave*.png', |
|
|
|
'sv_battle/RMMV/system/States.png', |
|
|
|
'tiles/TILESETS/animated/*.png', |
|
|
|
'patron/fireworks*_1.png', |
|
|
|
'pixelanimations/animationsheets/*.png', |
|
|
|
'ship/100/char/!$ship_wave*.png', |
|
|
|
'sv_battle/RMMV/system/States.png', |
|
|
|
'tiles/TILESETS/animated/*.png', |
|
|
|
] |
|
|
|
|
|
|
|
ICON_FILES = [ |
|
|
|
'farmandfort/IconSet/tf_icon_16.png', |
|
|
|
'halloween/hallowicons_1.png', |
|
|
|
'farmandfort/IconSet/tf_icon_16.png', |
|
|
|
'halloween/hallowicons_1.png', |
|
|
|
] |
|
|
|
|
|
|
|
BACKGROUND_FILES = [ |
|
|
|
'cloud/bg_*.png', |
|
|
|
'future/100/other/spacebg.png', |
|
|
|
'ship/100/parallax/*.png' |
|
|
|
'cloud/bg_*.png', |
|
|
|
'future/100/other/spacebg.png', |
|
|
|
'ship/100/parallax/*.png' |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
@ -92,7 +93,7 @@ def unglob(list_of_globs): |
|
|
|
result = [] |
|
|
|
for file in list_of_globs: |
|
|
|
globbed_files = glob.glob(file) |
|
|
|
assert len(globbed_files) > 0, 'glob for %s should be non-empty' % file |
|
|
|
assert globbed_files, 'glob for %s should be non-empty' % file |
|
|
|
result.extend(globbed_files) |
|
|
|
result.sort() |
|
|
|
return result |
|
|
@ -104,7 +105,7 @@ def input_wh(prompt): |
|
|
|
try: |
|
|
|
cols, rows = [int(x) for x in geometry.split(' ')] |
|
|
|
return cols, rows |
|
|
|
except: |
|
|
|
except ValueError: |
|
|
|
pass |
|
|
|
|
|
|
|
|
|
|
@ -179,16 +180,16 @@ def set_sprite_chunk_size(metadata): |
|
|
|
metadata['chunk_height'] = metadata['image_height'] // rows |
|
|
|
metadata['chunks'] = [] |
|
|
|
for i in range(cols * rows): |
|
|
|
x = i % cols |
|
|
|
y = i // cols |
|
|
|
chunk_md = { |
|
|
|
'index': i, |
|
|
|
'x': x * metadata['chunk_width'], |
|
|
|
'y': y * metadata['chunk_height'], |
|
|
|
'width': metadata['chunk_width'], |
|
|
|
'height': metadata['chunk_height'] |
|
|
|
} |
|
|
|
metadata['chunks'].append(chunk_md) |
|
|
|
x = i % cols |
|
|
|
y = i // cols |
|
|
|
chunk_md = { |
|
|
|
'index': i, |
|
|
|
'x': x * metadata['chunk_width'], |
|
|
|
'y': y * metadata['chunk_height'], |
|
|
|
'width': metadata['chunk_width'], |
|
|
|
'height': metadata['chunk_height'] |
|
|
|
} |
|
|
|
metadata['chunks'].append(chunk_md) |
|
|
|
render_sprite(metadata) |
|
|
|
|
|
|
|
|
|
|
@ -205,9 +206,9 @@ def edit_sprite_metadata(filename, metadata=None): |
|
|
|
if metadata is None: |
|
|
|
image = pygame.image.load(filename) |
|
|
|
metadata = { |
|
|
|
'filename': filename, |
|
|
|
'image_width': image.get_width(), |
|
|
|
'image_height': image.get_height(), |
|
|
|
'filename': filename, |
|
|
|
'image_width': image.get_width(), |
|
|
|
'image_height': image.get_height(), |
|
|
|
} |
|
|
|
|
|
|
|
print('\nprocessing %s (%dx%d)' % ( |
|
|
@ -240,15 +241,15 @@ def edit_sprite_metadata(filename, metadata=None): |
|
|
|
|
|
|
|
def annotate_sprites(all_metadata, sprite_files): |
|
|
|
pygame.init() |
|
|
|
surface = pygame.display.set_mode((1200, 900), pygame.RESIZABLE) |
|
|
|
pygame.display.set_mode((1200, 900), pygame.RESIZABLE) |
|
|
|
|
|
|
|
for filename in sprite_files: |
|
|
|
sprite_metadata, quit = edit_sprite_metadata( |
|
|
|
sprite_metadata, should_quit = edit_sprite_metadata( |
|
|
|
filename, all_metadata.get(filename)) |
|
|
|
all_metadata[filename] = sprite_metadata |
|
|
|
with open('sprites.json', 'w') as f: |
|
|
|
json.dump(all_metadata, f, sort_keys=True, indent=2) |
|
|
|
if quit: |
|
|
|
if should_quit: |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
@ -284,7 +285,8 @@ def stitch_sprites(metadata, filename_base): |
|
|
|
print('\n# named sprites:', len(sprites)) |
|
|
|
print('result will be %dx%d' % (total_width, max_height)) |
|
|
|
|
|
|
|
output = pygame.Surface((total_width, max_height), pygame.SRCALPHA) |
|
|
|
output = pygame.surface.Surface( |
|
|
|
(total_width, max_height), flags=pygame.SRCALPHA) |
|
|
|
output_json = {} |
|
|
|
xpos = 0 |
|
|
|
for sprite_name, sprite in sprites.items(): |
|
|
@ -292,11 +294,11 @@ def stitch_sprites(metadata, filename_base): |
|
|
|
area = pygame.Rect( |
|
|
|
sprite['x'], sprite['y'], sprite['width'], sprite['height']) |
|
|
|
output_json[sprite_name] = { |
|
|
|
'name': sprite['name'], |
|
|
|
'x': xpos, |
|
|
|
'y': 0, |
|
|
|
'width': sprite['width'], |
|
|
|
'height': sprite['height'] |
|
|
|
'name': sprite['name'], |
|
|
|
'x': xpos, |
|
|
|
'y': 0, |
|
|
|
'width': sprite['width'], |
|
|
|
'height': sprite['height'] |
|
|
|
} |
|
|
|
output.blit(sprite_image, (xpos, 0), area) |
|
|
|
xpos += sprite['width'] |
|
|
@ -309,7 +311,6 @@ def stitch_sprites(metadata, filename_base): |
|
|
|
json.dump(output_json, json_file, sort_keys=True, indent=2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main(args): |
|
|
|
os.chdir(os.path.expanduser('~/time_fantasy')) |
|
|
|
|
|
|
@ -319,8 +320,8 @@ def main(args): |
|
|
|
icon_files = unglob(ICON_FILES) |
|
|
|
background_files = unglob(BACKGROUND_FILES) |
|
|
|
print('\nsprites: %d tilesets: %d animations: %d icons: %d backgrounds: %d' % |
|
|
|
(len(sprite_files), len(tileset_files), len(animation_files), |
|
|
|
len(icon_files), len(background_files))) |
|
|
|
(len(sprite_files), len(tileset_files), len(animation_files), |
|
|
|
len(icon_files), len(background_files))) |
|
|
|
|
|
|
|
if len(args) < 1: |
|
|
|
return |
|
|
|