convert map and implement collisions

This commit is contained in:
Lephenixnoir 2020-12-22 17:01:59 +01:00
parent 76e2a7ed60
commit 80167969fe
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
9 changed files with 135 additions and 10 deletions

View File

@ -21,10 +21,11 @@ set(ASSETS
)
set(ASSETS_fx
assets-fx/levels.png
assets-fx/lv1.png
assets-fx/title.png
assets-fx/spritesheet.png
assets-fx/font_mystere.png
# ...
assets-fx/map/lv1.txt
)
set(ASSETS_cg
assets-cg/example.png
@ -32,6 +33,7 @@ set(ASSETS_cg
)
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
fxconv_declare_converters(assets-fx/converters.py)
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os)

Binary file not shown.

89
assets-fx/converters.py Normal file
View File

@ -0,0 +1,89 @@
import fxconv
import re
import os.path
def convert(input, output, params, target):
if params["custom-type"] == "map":
convert_map(input, output, params, target)
return 0
else:
return 1
def convert_map(input, output, params, target):
TILE_AIR = 0
TILE_WALL = 1
TILE_START = 2
TILE_END = 3
TILE_KEY = 16
TILE_VDOOR = 24
TILE_HDOOR = 32
# Read input file
with open(input, "r") as fp:
tiles, cycles = fp.read().split("\n\n")
tiles = tiles.split("\n")
cycle_texts = [c for c in cycles.split("\n") if c]
w = max(len(t) for t in tiles)
h = len(tiles)
fog = 0
filename = os.path.splitext(os.path.basename(input))[0]
# Generate map contents
encoded_tiles = bytearray(w * h)
for (y, t) in enumerate(tiles):
for (x, c) in enumerate(t):
if c == " ":
tile = TILE_AIR
elif c == "#":
tile = TILE_WALL
elif c == "~":
tile = TILE_START
elif c == "@":
tile = TILE_END
elif ord("0") <= ord(c) <= ord("9"):
tile = TILE_KEY + int(c)
elif ord("a") <= ord(c) <= ord("z"):
tile = TILE_VDOOR + (ord(c) - ord("a"))
elif ord("A") <= ord(c) <= ord("Z"):
tile = TILE_HDOOR + (ord(c) - ord("A"))
else:
raise fxconv.FxconvError(f"unknown tile character {c}")
encoded_tiles[y*w + x] = tile
# Parse door cycles
RE_CYCLE = re.compile(r'^([a-zA-Z]):\s*([#.]+)$')
cycles = dict()
for c in cycle_texts:
m = re.match(RE_CYCLE, c)
if not m:
raise fxconv.FxconvError(f"cannot parse door cycle '{c}'")
cycles[m[1]] = m[2].encode("utf-8")
# Generate door cycle data
door_cycle = b""
door_cycle_index = bytearray(16)
for index, letter in enumerate("abcdefghABCDEFGH"):
door_cycle_index[index] = len(door_cycle)
if letter in cycles:
door_cycle += cycles[letter] + b" "
door_cycle = door_cycle + bytes(128 - len(door_cycle))
# Generate the structure
o = fxconv.ObjectData()
o += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(fog)
o += door_cycle + door_cycle_index
o += fxconv.ref(f"img_{filename}")
o += fxconv.ref(encoded_tiles)
fxconv.elf(o, output, "_" + params["name"], **target)

BIN
assets-fx/lv1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

View File

@ -0,0 +1,3 @@
*.txt:
custom-type: map
name_regex: (.*)\.txt map_\1

10
assets-fx/map/lv1.txt Normal file
View File

@ -0,0 +1,10 @@
##### #####
# ##### #
# a a #
##A### ###A##
# a a #
# ~ ##### @ #
##### #####
a: #.
A: #.

View File

@ -40,6 +40,7 @@ static void engine_draw_player(struct player const *player)
void engine_draw(struct game const *game)
{
dclear(C_WHITE);
dimage(0, 0, game->map->img);
for(int p = 0; game->players[p]; p++)
{
@ -54,8 +55,8 @@ void engine_draw(struct game const *game)
/* Check whether a cell of the map is walkable */
static int map_walkable(struct map const *map, int x, int y)
{
/* TODO: Read the map's data array */
return (x >= 1) && (y >= 1) && (x < map->w - 1) && (y < map->h - 1);
int tile = map->tiles[y * map->w + x];
return (tile != TILE_WALL);
}
int engine_move(struct game *game, struct player *player, int dir)

View File

@ -37,8 +37,30 @@ struct map
int w, h;
/* Whether fog is enabled */
int fog;
/* Raw data */
uint8_t *data;
/* Door cycle string */
char door_cycle[128];
/* Mapping of door types to cycle string index */
uint8_t door_cycle_index[16];
/* Background image */
bopti_image_t *img;
/* Array of tiles in row-major order */
uint8_t *tiles;
};
/* enum map_tile: Single cell in the map */
enum map_tile
{
TILE_AIR = 0,
TILE_WALL = 1,
TILE_START = 2,
TILE_END = 3,
/* 8 keys in interval 16..23 */
TILE_KEY = 16,
/* 8 vertical doors in interval 24..31 */
TILE_VDOOR = 24,
/* 8 horizontal doors in interval 32..39 */
TILE_HDOOR = 32,
};
/* struct game: A running game with a map and some players */

View File

@ -97,12 +97,10 @@ int main(void)
};
singleplayer.idle = !anim_player_idle(&singleplayer.anim, 1);
struct map map = {
.w = 13,
.h = 7
};
extern struct map map_lv1;
struct game game = {
.map = &map,
.map = &map_lv1,
.players = { &singleplayer, NULL },
.time = 0,
};