Read in tile data from tilemap

This commit is contained in:
2025-06-20 00:24:34 -05:00
parent 1022f45565
commit 2a8183e9a3
9 changed files with 98 additions and 64 deletions

View File

@ -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)",

View File

@ -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;

View File

@ -8,5 +8,4 @@ target_sources(${DUSK_TARGET_NAME}
PRIVATE PRIVATE
chunk.c chunk.c
overworld.c overworld.c
tile.c
) )

View File

@ -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"

View File

@ -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))

View File

@ -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)

View File

@ -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']):

View File

@ -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)

View File

@ -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")