From 8fa119937d7efee57b7b8d6a730266e72795f3f9 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Thu, 20 Aug 2020 17:04:31 +0200 Subject: [PATCH] add a walkable map --- MystNB.g1a | Bin 22672 -> 24916 bytes assets-fx/img/spritesheet.png | Bin 0 -> 1071 bytes src/engine.c | 56 ++++++++++++++++++++++++++++++++ src/engine.h | 55 +++++++++++++++++++++++++++++++ src/main.c | 59 +++++++++++++++++++++++++++++++++- 5 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 assets-fx/img/spritesheet.png create mode 100644 src/engine.c create mode 100644 src/engine.h diff --git a/MystNB.g1a b/MystNB.g1a index 82e0a74051ab9c40d773c93f19850811a02ff3fe..78e73bee4b65c8d6e4d436bc85a24170417e35f7 100644 GIT binary patch delta 5744 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 HiNpT^0h-^@ delta 3715 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 diff --git a/assets-fx/img/spritesheet.png b/assets-fx/img/spritesheet.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbfcd1f723d35b5281998c7aeb854c1641c3cb2 GIT binary patch literal 1071 zcmV+~1kn45P)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00WmvL_t(|+U;Chj_V){Ehwv= z1$5PwxIg6zh@XT6?1EIyOa{!c0ULZmL;Ad5yUZ&``yd>Dsr);A-hmRJso&P^X)_Yf z3iw000sn#WMbQ8l9pt)EFGm zrp>6*Bi9=K2sH>HR6nU@U(Fh%e)ap;D3o!^`jt$^I2Q58CnG)tVC0Omh`$}nsMBAP2fWz!{+*u9f>9Uu^cJLr*X?t(e;!t-nQg z8-b^Y z$eMk1;({MluUEddkMwzm_7p0?U(QlWz9z>6>HO`hl7BR_AvL3&$U{ugh6B|jU)u+; z62$l=vsoKQTI|pY2s<4;x5RCNx#jSt&{aNQMCw{2`{aV8fL2l9N*~f3zv%E+#vTQC z5G8=Z@t3$9JXN0q1m)@}+1&FHe89*Ao`?^C6rcdDq5yR=y}}1z>FC~*KZYf8M{7x{ z;3);9h8)2MjK~E^WQqwHiSh4NU^aJfJ0DL#Y*a*iK(7K|N_PSw)58a7Uo{!&hELnjD};t7pROfjX7B;zf$UB`0Lynv z2os5WfZRz>yHR`qq_5~ytl$IkOsDj9#|LOm-x@qn{Sorr@d46$T0Btw5%M=5Fu80# zU~+NK2WV5+qh5WN%6H|0?s|t`%Liy=M~}uIkxsvIP`h+Lz#PS@f~?set@^tMa}G=+=iOx11tw%t9-!W-BnO=pyUIvcQ+;O2J1ue?x~9vV2KZK8w2jV z-|+bT01v@<1wH`6Bf2AIIS`**5SNxN+OVAP=N&YMG6|*XG8d#Z(uh-Uul&si>>&Kx zW%B{6-4F0)d{X(Ky<8 literal 0 HcmV?d00001 diff --git a/src/engine.c b/src/engine.c new file mode 100644 index 0000000..d5fe81d --- /dev/null +++ b/src/engine.c @@ -0,0 +1,56 @@ +#include +#include +#include "engine.h" + +#define CELL_X(x) (-2 + 10 * (x)) +#define CELL_Y(y) (-3 + 10 * (y)) + +//--- +// Rendering +//--- + +static void engine_draw_player(struct player const *player) +{ + extern bopti_image_t img_spritesheet; + + dsubimage(CELL_X(player->x) - 1, CELL_Y(player->y) - 5, + &img_spritesheet, player->dir * 12, 0, 12, 16, DIMAGE_NONE); +} + +void engine_draw(struct game const *game) +{ + dclear(C_WHITE); + + for(int p = 0; game->players[p]; p++) + { + engine_draw_player(game->players[p]); + } +} + +//--- +// Physics +//--- + +/* 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 engine_move(struct game *game, struct player *player, int dir) +{ + int dx = (dir == DIR_RIGHT) - (dir == DIR_LEFT); + int dy = (dir == DIR_DOWN) - (dir == DIR_UP); + + /* Always update the direction */ + player->dir = dir; + + /* Only move the player if the destination is walkable */ + if(!map_walkable(game->map, player->x + dx, player->y + dy)) return 0; + + player->x += dx; + player->y += dy; + + return 1; +} diff --git a/src/engine.h b/src/engine.h new file mode 100644 index 0000000..2dc81bf --- /dev/null +++ b/src/engine.h @@ -0,0 +1,55 @@ +#ifndef _MYSTNB_ENGINE_H +#define _MYSTNB_ENGINE_H + +#include + +#define PLAYER_COUNT 1 + +/* Directions */ +#define DIR_DOWN 0 +#define DIR_RIGHT 1 +#define DIR_UP 2 +#define DIR_LEFT 3 + +/* struct player: A player on the map, triggering actions as they move */ +struct player +{ + /* Position in map */ + int x, y; + /* Direction currently facing */ + int dir; + /* Animation and frame */ + struct animation const *anim; + int frame; +}; + +/* struct map: A map with moving doors, collectibles, and fog */ +struct map +{ + /* Width and height */ + int w, h; + /* Whether fog is enabled */ + int fog; + /* Raw data */ + uint8_t *data; +}; + +/* struct game: A running game with a map and some players */ +struct game +{ + /* Current map */ + struct map *map; + /* Players */ + struct player *players[PLAYER_COUNT + 1]; + /* Current game time (ms) */ + int time; +}; + +/* Draw the current game frame from scratch; does not dupdate() */ +void engine_draw(struct game const *game); + +/* Try to move a player along a direction. Returns 1 if the move is successful, + 0 otherwise (collisions or out-of-bounds moves) */ +int engine_move(struct game *game, struct player *player, int direction); + +#endif /* _MYSTNB_ENGINE_H */ diff --git a/src/main.c b/src/main.c index 0a72769..7e23c40 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,8 @@ #include #include +#include "engine.h" + static void draw_menu(int selected) { extern bopti_image_t img_title; @@ -31,7 +33,7 @@ static void draw_menu(int selected) } } -int main(void) +static int main_menu(void) { extern font_t font_mystere; dfont(&font_mystere); @@ -52,5 +54,60 @@ int main(void) selected++; } + return selected; +} + +/* Returns a direction to move in */ +static int get_inputs(void) +{ + int opt = GETKEY_DEFAULT & ~GETKEY_REP_ARROWS; + + while(1) + { + int key = getkey_opt(opt, NULL).key; + + if(key == KEY_DOWN) return DIR_DOWN; + if(key == KEY_RIGHT) return DIR_RIGHT; + if(key == KEY_UP) return DIR_UP; + if(key == KEY_LEFT) return DIR_LEFT; + } +} + +int main(void) +{ + GUNUSED int level = main_menu(); + + struct player singleplayer = { + .x = 2, + .y = 3 + }; + struct map map = { + .w = 13, + .h = 7 + }; + struct game game = { + .map = &map, + .players = { &singleplayer, NULL }, + .time = 0, + }; + + int level_finished = 0; + + while(!level_finished) + { + int turn_finished = 0; + while(!turn_finished) + { + engine_draw(&game); + dupdate(); + stream_mono(); + + int dir = get_inputs(); + turn_finished = engine_move(&game, &singleplayer, dir); + } + + /* Update doors, etc */ + } + return 1; }