Read in tile data from tilemap
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"activeFile": "map.tmj",
|
"activeFile": "overworld.tsx",
|
||||||
"expandedProjectPaths": [
|
"expandedProjectPaths": [
|
||||||
"templates",
|
"templates",
|
||||||
"."
|
"."
|
||||||
@ -13,16 +13,16 @@
|
|||||||
"scaleInEditor": 1
|
"scaleInEditor": 1
|
||||||
},
|
},
|
||||||
"map.tmj": {
|
"map.tmj": {
|
||||||
"scale": 3,
|
"scale": 4,
|
||||||
"selectedLayer": 2,
|
"selectedLayer": 2,
|
||||||
"viewCenter": {
|
"viewCenter": {
|
||||||
"x": 6665.833333333333,
|
"x": 6625.125,
|
||||||
"y": 6701.5
|
"y": 6667.875
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overworld.tsx": {
|
"overworld.tsx": {
|
||||||
"scaleInDock": 1,
|
"scaleInDock": 1,
|
||||||
"scaleInEditor": 8
|
"scaleInEditor": 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"last.externalTilesetPath": "/home/yourwishes/htdocs/dusk/data",
|
"last.externalTilesetPath": "/home/yourwishes/htdocs/dusk/data",
|
||||||
@ -35,8 +35,8 @@
|
|||||||
"project": "map project.tiled-project",
|
"project": "map project.tiled-project",
|
||||||
"property.type": "int",
|
"property.type": "int",
|
||||||
"recentFiles": [
|
"recentFiles": [
|
||||||
"overworld.tsx",
|
|
||||||
"map.tmj",
|
"map.tmj",
|
||||||
|
"overworld.tsx",
|
||||||
"entities.tsx"
|
"entities.tsx"
|
||||||
],
|
],
|
||||||
"tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)",
|
"tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)",
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "world/world.h"
|
#include "world/world.h"
|
||||||
|
#include "world/tiledata.h"
|
||||||
#include "physics/physics.h"
|
#include "physics/physics.h"
|
||||||
|
|
||||||
entity_t ENTITIES[ENTITY_COUNT_MAX] = {0};
|
entity_t ENTITIES[ENTITY_COUNT_MAX] = {0};
|
||||||
@ -89,14 +90,10 @@ void entityUpdate(entity_t *entity) {
|
|||||||
uint8_t chunkTileX = tileX % CHUNK_WIDTH;
|
uint8_t chunkTileX = tileX % CHUNK_WIDTH;
|
||||||
uint8_t chunkTileY = tileY % CHUNK_HEIGHT;
|
uint8_t chunkTileY = tileY % CHUNK_HEIGHT;
|
||||||
tile_t tile = chunk->tilesBase[chunkTileY * CHUNK_WIDTH + chunkTileX];
|
tile_t tile = chunk->tilesBase[chunkTileY * CHUNK_WIDTH + chunkTileX];
|
||||||
|
|
||||||
tilesolidtype_t solidType = (
|
|
||||||
tile < TILE_META_DATA_COUNT ? TILE_META_DATA[tile].solidType :
|
|
||||||
TILE_SOLID_NONE
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Determine tile collision type
|
||||||
collisionresult_t collision;
|
collisionresult_t collision;
|
||||||
switch(solidType) {
|
switch(TILE_META_DATA[tile].solidType) {
|
||||||
case TILE_SOLID_FULL:
|
case TILE_SOLID_FULL:
|
||||||
collision = physicsCheckCircleAABB(
|
collision = physicsCheckCircleAABB(
|
||||||
newX, newY, selfCircR,
|
newX, newY, selfCircR,
|
||||||
@ -105,6 +102,7 @@ void entityUpdate(entity_t *entity) {
|
|||||||
FIXED248(TILE_WIDTH_HEIGHT, 0),
|
FIXED248(TILE_WIDTH_HEIGHT, 0),
|
||||||
FIXED248(TILE_WIDTH_HEIGHT, 0)
|
FIXED248(TILE_WIDTH_HEIGHT, 0)
|
||||||
);
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -8,5 +8,4 @@ target_sources(${DUSK_TARGET_NAME}
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
chunk.c
|
chunk.c
|
||||||
overworld.c
|
overworld.c
|
||||||
tile.c
|
|
||||||
)
|
)
|
@ -1,8 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tile.h"
|
|
@ -23,30 +23,4 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
tilesolidtype_t solidType;
|
tilesolidtype_t solidType;
|
||||||
} tilemeta_t;
|
} tilemetadata_t;
|
||||||
|
|
||||||
static const tilemeta_t TILE_META_DATA[] = {
|
|
||||||
{TILE_SOLID_NONE}, // 0
|
|
||||||
{TILE_SOLID_NONE}, // 1
|
|
||||||
{TILE_SOLID_NONE}, // 2
|
|
||||||
{TILE_SOLID_NONE}, // 3
|
|
||||||
{TILE_SOLID_NONE}, // 4
|
|
||||||
{TILE_SOLID_NONE}, // 5
|
|
||||||
{TILE_SOLID_NONE}, // 6
|
|
||||||
{TILE_SOLID_NONE}, // 7
|
|
||||||
{TILE_SOLID_NONE}, // 8
|
|
||||||
{TILE_SOLID_NONE}, // 9
|
|
||||||
{TILE_SOLID_NONE}, // 10
|
|
||||||
{TILE_SOLID_NONE}, // 11
|
|
||||||
{TILE_SOLID_NONE}, // 12
|
|
||||||
{TILE_SOLID_NONE}, // 13
|
|
||||||
{TILE_SOLID_NONE}, // 14
|
|
||||||
{TILE_SOLID_NONE}, // 15
|
|
||||||
{TILE_SOLID_NONE}, // 16
|
|
||||||
{TILE_SOLID_NONE}, // 17
|
|
||||||
{TILE_SOLID_FULL}, // 18
|
|
||||||
{TILE_SOLID_FULL}, // 19
|
|
||||||
{TILE_SOLID_FULL}, // 19
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TILE_META_DATA_COUNT (sizeof(TILE_META_DATA) / sizeof(tilemeta_t))
|
|
@ -4,4 +4,5 @@
|
|||||||
# https://opensource.org/licenses/MIT
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
add_subdirectory(mapcompile)
|
add_subdirectory(mapcompile)
|
||||||
|
add_subdirectory(tilecompile)
|
@ -174,9 +174,6 @@ for chunk in firstLayer['chunks']:
|
|||||||
inputMapHighestX += inputLayerWidthInTiles
|
inputMapHighestX += inputLayerWidthInTiles
|
||||||
inputMapHighestY += inputLayerHeightInTiles
|
inputMapHighestY += inputLayerHeightInTiles
|
||||||
|
|
||||||
print(f"Input map lowest X: {inputMapLowestX}, highest X: {inputMapHighestX}")
|
|
||||||
print(f"Input map lowest Y: {inputMapLowestY}, highest Y: {inputMapHighestY}")
|
|
||||||
|
|
||||||
# We now offset all chunks by the lowest X/Y values to make them start at (0, 0).
|
# We now offset all chunks by the lowest X/Y values to make them start at (0, 0).
|
||||||
for layerIndex, layer in enumerate(tileLayers):
|
for layerIndex, layer in enumerate(tileLayers):
|
||||||
for chunkIndex, chunk in enumerate(layer['chunks']):
|
for chunkIndex, chunk in enumerate(layer['chunks']):
|
||||||
|
@ -6,16 +6,15 @@
|
|||||||
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
||||||
|
|
||||||
# Custom command to generate all header files
|
# Custom command to generate all header files
|
||||||
add_custom_target(DUSK_CHUNKS
|
add_custom_target(DUSK_TILES
|
||||||
# OUTPUT ${DUSK_GENERATED_HEADERS_DIR}/world/world.h
|
|
||||||
COMMAND
|
COMMAND
|
||||||
${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/mapcompile.py
|
${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tilecompile.py
|
||||||
--output ${DUSK_GENERATED_HEADERS_DIR}
|
--output ${DUSK_GENERATED_HEADERS_DIR}
|
||||||
--input ${DUSK_DATA_DIR}/map.tmj
|
--input ${DUSK_DATA_DIR}/overworld.tsx
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mapcompile.py
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tilecompile.py
|
||||||
COMMENT "Generating chunk header files"
|
COMMENT "Generating tile header file"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
|
||||||
# Ensure headers are generated before compiling main
|
# Ensure headers are generated before compiling main
|
||||||
add_dependencies(${DUSK_TARGET_NAME} DUSK_CHUNKS)
|
add_dependencies(${DUSK_TARGET_NAME} DUSK_TILES)
|
@ -1,13 +1,12 @@
|
|||||||
import sys, os
|
import sys, os
|
||||||
import argparse
|
import argparse
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import xml.etree.ElementTree as ET
|
||||||
import math
|
|
||||||
|
|
||||||
# Check if the script is run with the correct arguments
|
# Check if the script is run with the correct arguments
|
||||||
parser = argparse.ArgumentParser(description="Generate chunk header files")
|
parser = argparse.ArgumentParser(description="Generate chunk header files")
|
||||||
parser.add_argument('--output', required=True, help='Dir to output headers')
|
parser.add_argument('--output', required=True, help='Dir to output headers')
|
||||||
parser.add_argument('--input', required=True, help='Input JSON file from tiled')
|
parser.add_argument('--input', required=True, help='Input XML file from tiled')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Ensure outdir exists
|
# Ensure outdir exists
|
||||||
@ -28,5 +27,80 @@ if not os.path.isfile(inputFile):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
with open(inputFile, 'r') as f:
|
with open(inputFile, 'r') as f:
|
||||||
data = json.load(f)
|
data = f.read()
|
||||||
|
|
||||||
|
# Parse the XML data
|
||||||
|
try:
|
||||||
|
root = ET.fromstring(data)
|
||||||
|
except ET.ParseError as e:
|
||||||
|
print(f"Error parsing XML: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if root.tag != 'tileset':
|
||||||
|
print("Error: Input file is not a valid Tiled XML file.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if 'tilewidth' not in root.attrib or 'tileheight' not in root.attrib:
|
||||||
|
print("Error: Missing tilewidth or tileheight attributes in the tileset.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if 'tilecount' not in root.attrib or 'columns' not in root.attrib:
|
||||||
|
print("Error: Missing tilecount or columns attributes in the tileset.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
tileWidth = int(root.get('tilewidth', 0))
|
||||||
|
tileHeight = int(root.get('tileheight', 0))
|
||||||
|
tileCount = int(root.get('tilecount', 0)) + 1 # +1 because maps are 1 indexed
|
||||||
|
columns = int(root.get('columns', 0))
|
||||||
|
|
||||||
|
tilesById = {}
|
||||||
|
for tile in root.findall('tile'):
|
||||||
|
if 'id' not in tile.attrib:
|
||||||
|
print("Error: Tile element missing 'id' attribute.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
tileId = int(tile.get('id', -1)) + 1 # +1 because maps are 1 indexed
|
||||||
|
if tileId < 0 or tileId >= tileCount:
|
||||||
|
print(f"Error: Invalid tile ID {tileId} in tile element.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
tilesById[tileId] = tile
|
||||||
|
|
||||||
|
# Create the header file
|
||||||
|
headerFile = os.path.join(worldDir, "tiledata.h")
|
||||||
|
with open(headerFile, 'w') as f:
|
||||||
|
f.write(f"// Generated on {now}\n")
|
||||||
|
f.write(f"#include \"world/tile.h\"\n\n")
|
||||||
|
f.write(f"#define TILE_WIDTH {tileWidth}\n")
|
||||||
|
f.write(f"#define TILE_HEIGHT {tileHeight}\n")
|
||||||
|
f.write(f"#define TILE_WIDTH_HEIGHT {tileWidth}\n")
|
||||||
|
f.write(f"#define TILE_COUNT {tileCount}\n")
|
||||||
|
|
||||||
|
f.write("static const tilemetadata_t TILE_META_DATA[TILE_COUNT] = {\n")
|
||||||
|
for tileId in range(tileCount):
|
||||||
|
tile = tilesById.get(tileId, None)
|
||||||
|
if tile is None:
|
||||||
|
f.write(f" {{ 0 }},\n")
|
||||||
|
continue
|
||||||
|
|
||||||
|
properties = tile.find('properties')
|
||||||
|
if properties is None:
|
||||||
|
f.write(f" {{ 0 }},\n")
|
||||||
|
continue
|
||||||
|
|
||||||
|
def findProp(name, expectedType=''):
|
||||||
|
for prop in properties.findall('property'):
|
||||||
|
if prop.get('name') == name:
|
||||||
|
if len(expectedType) > 0 and prop.get('type') != expectedType:
|
||||||
|
continue
|
||||||
|
return prop.get('value', '')
|
||||||
|
return None
|
||||||
|
|
||||||
|
f.write(f" {{\n")
|
||||||
|
|
||||||
|
propSolid = findProp('solid', 'int')
|
||||||
|
if propSolid is not None:
|
||||||
|
f.write(f" .solidType = {propSolid},\n")
|
||||||
|
|
||||||
|
f.write(f" }},\n")
|
||||||
|
f.write("};\n\n")
|
Reference in New Issue
Block a user