add a walkable map

This commit is contained in:
Lephenixnoir 2020-08-20 17:04:31 +02:00
parent ebf924958d
commit 8dba2daeb3
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
7 changed files with 172 additions and 7 deletions

View File

@ -11,6 +11,7 @@ find_package(Gint 2.1 REQUIRED)
set(SOURCES
src/main.c
src/engine.c
# ...
)
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets
@ -20,6 +21,7 @@ set(ASSETS
set(ASSETS_fx
assets-fx/levels.png
assets-fx/title.png
assets-fx/spritesheet.png
assets-fx/font_mystere.png
# ...
)

Binary file not shown.

View File

@ -1,10 +1,6 @@
levels.png:
*.png:
type: bopti-image
name: img_levels
title.png:
type: bopti-image
name: img_title
name_regex: (.*)\.png img_\1
font_mystere.png:
type: font

BIN
assets-fx/spritesheet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

56
src/engine.c Normal file
View File

@ -0,0 +1,56 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#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;
}

55
src/engine.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef _MYSTNB_ENGINE_H
#define _MYSTNB_ENGINE_H
#include <stdint.h>
#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 */

View File

@ -1,6 +1,8 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#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,59 @@ 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();
int dir = get_inputs();
turn_finished = engine_move(&game, &singleplayer, dir);
}
/* Update doors, etc */
}
return 1;
}