Import LDTK maps
This commit is contained in:
parent
f6d942c614
commit
055b3dd7b1
16
game/BUILD
16
game/BUILD
@ -2,8 +2,8 @@ load("@bazel_skylib//rules:run_binary.bzl", "run_binary")
|
||||
|
||||
cc_library(
|
||||
name = "game",
|
||||
srcs = glob(["*.c"]) + [":art/game_demo_sprites.c"],
|
||||
hdrs = glob(["*.h"]) + [":art/game_demo_sprites.h"],
|
||||
srcs = glob(["*.c"]) + [":art/game_demo_sprites.c", ":map/game_map.c"],
|
||||
hdrs = glob(["*.h"]) + [":art/game_demo_sprites.h", ":map/game_map.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//device:device", "//sys:sys"]
|
||||
)
|
||||
@ -20,4 +20,16 @@ run_binary(
|
||||
srcs = [":art/game_demo_sprites.png"],
|
||||
outs = [":art/game_demo_sprites.c"],
|
||||
tool = "//pytools:spritesheet",
|
||||
)
|
||||
|
||||
run_binary(
|
||||
name = "game_map",
|
||||
args = [
|
||||
"game_map",
|
||||
"$(location :map/crocparty.ldtk)",
|
||||
"$(location :map/game_map.c)",
|
||||
],
|
||||
srcs = [":map/crocparty.ldtk"],
|
||||
outs = [":map/game_map.c"],
|
||||
tool = "//pytools:mapdata"
|
||||
)
|
2155
game/map/crocparty.ldtk
Normal file
2155
game/map/crocparty.ldtk
Normal file
File diff suppressed because one or more lines are too long
5
game/map/game_map.h
Normal file
5
game/map/game_map.h
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef CROCPARTY_GAME_MAP_H
|
||||
#define CROCPARTY_GAME_MAP_H
|
||||
|
||||
#endif
|
||||
|
@ -18,4 +18,14 @@ py_binary(
|
||||
requirement("Jinja2"),
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
py_binary(
|
||||
name = "mapdata",
|
||||
srcs = ["mapdata.py", "shared.py"],
|
||||
deps = [
|
||||
requirement("pillow"),
|
||||
requirement("Jinja2"),
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
90
pytools/mapdata.py
Normal file
90
pytools/mapdata.py
Normal file
@ -0,0 +1,90 @@
|
||||
import sys
|
||||
import json
|
||||
import shared
|
||||
|
||||
TEMPLATE = """
|
||||
// generated code! be nice
|
||||
#include "sys/sys.h"
|
||||
|
||||
sys_i32 {{map_name}}_player_start_x = {{player_start.0}};
|
||||
sys_i32 {{map_name}}_player_start_y = {{player_start.1}};
|
||||
|
||||
sys_maptile {{map_name}}_data[{{width * height}}] = { {{ tiles|join(",") }} };
|
||||
sys_map {{map_name}} = {
|
||||
.tiles={{map_name}}_data,
|
||||
.width={{width}},
|
||||
.height={{height}},
|
||||
};
|
||||
""".lstrip()
|
||||
|
||||
def main(map_name, fname_ldtk, fname_c):
|
||||
width, height, tiles, player_start = load_mapdata(fname_ldtk)
|
||||
|
||||
with open(fname_c, "wt") as output:
|
||||
output.write(
|
||||
shared.templates.from_string(TEMPLATE).render(
|
||||
map_name=map_name,
|
||||
player_start=player_start,
|
||||
tiles=tiles,
|
||||
width=width,
|
||||
height=height,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def load_mapdata(fname_ldtk):
|
||||
sparse_tiles = {}
|
||||
player_start_xy = None
|
||||
with open(fname_ldtk, "rt") as f:
|
||||
data = json.load(f)
|
||||
for level in data["levels"]:
|
||||
level_x = level["worldX"] // 8
|
||||
level_y = level["worldY"] // 8
|
||||
for layer in level["layerInstances"]:
|
||||
w = layer["__cWid"]
|
||||
h = layer["__cHei"]
|
||||
|
||||
if layer["__identifier"] == "vague":
|
||||
# for right now I use the vague layer to assign tiles
|
||||
for x, y, ix in annot_xy(layer["intGridCsv"], w, h):
|
||||
if ix == 0:
|
||||
continue
|
||||
sparse_tiles[level_x + x, level_y + y] = ix
|
||||
|
||||
if layer["__identifier"] == "entities":
|
||||
for e in layer["entityInstances"]:
|
||||
x, y = e["__grid"]
|
||||
player_start_xy = (level_x + x, level_y + y)
|
||||
|
||||
assert player_start_xy is not None, "player start not found"
|
||||
x_min = 0
|
||||
y_min = 0
|
||||
assert not any(x for (x, _) in sparse_tiles if x < x_min), "level can't be left of (0, 0)"
|
||||
assert not any(y for (_, y) in sparse_tiles if y < y_min), "level can't be up from (0, 0)"
|
||||
width = max(x for (x, _) in sparse_tiles) + 1
|
||||
height = max(y for (_, y) in sparse_tiles) + 1
|
||||
dense_tiles = []
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
k = (x, y)
|
||||
if k in sparse_tiles:
|
||||
dense_tiles.append(sparse_tiles[k])
|
||||
else:
|
||||
dense_tiles.append(0)
|
||||
|
||||
return width, height, dense_tiles, player_start_xy
|
||||
|
||||
|
||||
|
||||
|
||||
def annot_xy(lst, w, h):
|
||||
assert len(lst) == w * h
|
||||
for y in range(h):
|
||||
for x in range(w):
|
||||
yield x, y, lst[y * w + x]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
assert len(sys.argv) == 4, \
|
||||
"there must be three args (map name, src ldtk, out c)"
|
||||
main(sys.argv[1], sys.argv[2], sys.argv[3])
|
@ -16,7 +16,7 @@ sys_sprite {{spritesheet_name}}_data[{{n_sprites}}] = {
|
||||
{%- endfor %}
|
||||
};
|
||||
sys_spritesheet {{spritesheet_name}} = {
|
||||
.sprites=&{{spritesheet_name}}_data,
|
||||
.sprites={{spritesheet_name}}_data,
|
||||
.width={{width}},
|
||||
.height={{height}},
|
||||
};
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
typedef int32_t sys_i32;
|
||||
typedef uint8_t sys_color;
|
||||
typedef uint8_t sys_maptile;
|
||||
typedef uint32_t sys_screen_color;
|
||||
typedef uint64_t sys_glyph;
|
||||
typedef struct {
|
||||
@ -20,6 +21,11 @@ typedef struct {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} sys_spritesheet;
|
||||
typedef struct {
|
||||
sys_maptile* tiles;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} sys_map;
|
||||
|
||||
sys_screen_color sys_make_screen_color(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
@ -28,4 +34,4 @@ sys_i32 sys_min_i32(sys_i32 x, sys_i32 y);
|
||||
sys_i32 sys_abs_i32(sys_i32 x);
|
||||
sys_i32 sys_sgn_i32(sys_i32 x);
|
||||
|
||||
#endif // CROCPARTY_SYS_DATA_H
|
||||
#endif // CROCPARTY_SYS_DATA_H
|
||||
|
Loading…
Reference in New Issue
Block a user