Add LDtk converter
The script generate a levelpack to be parsed into the gamescene_man
parent
cb703877cb
commit
396551a572
|
@ -1,2 +1,3 @@
|
|||
*
|
||||
!.gitignore
|
||||
!ldtk_repacker.py
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
import sys
|
||||
import argparse
|
||||
import pprint
|
||||
import json
|
||||
import struct
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('filename')
|
||||
args = parser.parse_args()
|
||||
|
||||
print("Parsing", args.filename)
|
||||
|
||||
with open(args.filename, 'r') as f:
|
||||
level_pack_data = json.load(f)
|
||||
|
||||
#pprint.pprint(level_pack_data)
|
||||
ENUMIDS_TILETYPE_MAPPING = {
|
||||
'Solid': 1,
|
||||
'Water': 2
|
||||
}
|
||||
|
||||
# First go to tilesets and find Simple_tiles identifier, then find enumTags to identifier which tile type is what tileid
|
||||
ids_tiletype_map = {}
|
||||
tileset_defs = level_pack_data["defs"]["tilesets"]
|
||||
|
||||
for ts_def in tileset_defs:
|
||||
if ts_def["identifier"] != "Simple_tiles":
|
||||
continue
|
||||
for tag in ts_def["enumTags"]:
|
||||
ids_tiletype_map[tag["tileIds"][0]] = ENUMIDS_TILETYPE_MAPPING[tag["enumValueId"]]
|
||||
|
||||
if not ids_tiletype_map:
|
||||
print("No tileset definition")
|
||||
sys.exit(1)
|
||||
|
||||
pprint.pprint(ids_tiletype_map)
|
||||
|
||||
# Number of levels is the length of the levels
|
||||
n_levels = len(level_pack_data["levels"])
|
||||
print("Number of levels:", n_levels)
|
||||
|
||||
fileparts = args.filename.split('.')
|
||||
if len(fileparts) == 1:
|
||||
fileparts.append("lvldat")
|
||||
else:
|
||||
fileparts[-1] = "lvldata"
|
||||
converted_filename = '.'.join(fileparts)
|
||||
|
||||
# Each level should be packed as: [width, 2 bytes][height, 2 bytes][tile_type,entity,water,padding 1,1,1,1 bytes][tile_type,entity,water,padding 1,1,1,1 bytes]...
|
||||
with open(converted_filename, 'wb+') as out_file:
|
||||
out_file.write(struct.pack("I", n_levels))
|
||||
# Then loop the levels. Read the layerIndstances
|
||||
for level in level_pack_data["levels"]:
|
||||
# Search for __identifier for the level layout
|
||||
level_name = level["identifier"]
|
||||
print("Parsing level", level_name)
|
||||
|
||||
|
||||
level_layout = {}
|
||||
for layer in level['layerInstances']:
|
||||
if layer["__identifier"] != "Tiles":
|
||||
continue
|
||||
|
||||
level_layout = layer
|
||||
|
||||
# Dimensions of each level is obtained via __cWid and __cHei. Get the __gridSize as well
|
||||
width = level_layout["__cWid"]
|
||||
height = level_layout["__cHei"]
|
||||
print(f"Dim.: {width}x{height}")
|
||||
# Create a W x H array of tile information
|
||||
n_tiles = width * height
|
||||
tiles_info = [[0,0,0] for _ in range(n_tiles)]
|
||||
# Loop through gridTiles, get "d" as the index to fill the info
|
||||
for tile in level_layout["gridTiles"]:
|
||||
tiles_info[tile["d"][0]][0] = ids_tiletype_map[tile["t"]]
|
||||
|
||||
out_file.write(struct.pack("32s2H", level_name.encode('utf-8'), width, height))
|
||||
for tile in tiles_info:
|
||||
out_file.write(struct.pack("3Bx", *tile))
|
||||
|
||||
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
print(tiles_info[y*width + x], end=" ")
|
||||
print()
|
||||
|
Loading…
Reference in New Issue