14. Parsing Ldtk Data
[[programvideogames]]In this lecture we'll be parsing the data from our LDtk level.
For now, we'll just focus on creating solid tiles where the solid tiles should be.
Odin comes with a JSON parser built in, and the LDtk is JSON - so that's handy.
Later, we'll want to write smaller JSON (or a custom format - that's more fun), that we could ship with the game because LDtk files are massive.
Before we edit the loading data, we'll define some types that the JSON parser will need:
LDtk_Data :: struct {
levels: []LDtk_Level,
}
LDtk_Level :: struct {
identifier: string,
layerInstances: []LDtk_Layer_Instance,
}
LDtk_Layer_Instance :: struct {
__identifier: string,
__type: string,
__cWid, __cHei: int,
intGridCsv: []int,
autoLayerTiles: []LDtk_Auto_Layer_Tile,
entityInstances: []LDtk_Entity,
}
LDtk_Auto_Layer_Tile :: struct {
px: [2]f32,
}
LDtk_Entity :: struct {
__identifier: string,
__worldX: f32,
__worldY: f32,
}
Here's the new loading data in full.
We entirely replace the old code with this.
// Load level data
{
level_data, ok := os.read_entire_file("data/world.ldtk", allocator = context.allocator)
assert(ok, "Failed to load level data")
ldtk_data := new(LDtk_Data, context.temp_allocator)
err := json.unmarshal(level_data, ldtk_data, allocator = context.temp_allocator)
if err != nil {
fmt.println(err)
return
}
for level in ldtk_data.levels {
if level.identifier != "Level_0" do continue
for layer in level.layerInstances {
switch layer.__identifier {
case "Entities":
for entity in layer.entityInstances {
switch entity.__identifier {
case "Player":
px, py := entity.__worldX, entity.__worldY
gs.player_id = entity_create(
{
x = px,
y = py,
width = 16,
height = 38,
move_speed = 280,
jump_force = 650,
on_enter = player_on_enter,
health = 5,
max_health = 5,
debug_color = rl.GREEN,
texture = &player_texture,
animations = {
"idle" = player_anim_idle,
"jump" = player_anim_jump,
"jump_fall_inbetween" = player_anim_jump_fall_inbetween,
"fall" = player_anim_fall,
"run" = player_anim_run,
"attack" = player_anim_attack,
},
current_anim_name = "idle",
},
)
case "Door":
}
}
case "Collisions":
x, y: f32
for v, i in layer.intGridCsv {
if v != 0 {
append(&gs.solid_tiles, Rect{x, y, TILE_SIZE, TILE_SIZE})
}
x += TILE_SIZE
if (i + 1) % layer.__cWid == 0 {
y += TILE_SIZE
x = 0
}
}
}
}
}
}
This code is following the LDtk JSON structure, loading the player position and solid tiles.
Select a file to view its contents.