Add stage selection screen

This commit is contained in:
Juhani Krekelä 2022-01-15 16:06:08 +00:00
parent d0eb8dab8e
commit 220ee0e453
4 changed files with 98 additions and 8 deletions

View File

@ -2,7 +2,7 @@
.SUFFIXES: .inc .txt
NAME = platformer
TILES = grass_tile.inc dirt_tile.inc flag_tile.inc
TILES = grass_tile.inc dirt_tile.inc flag_tile.inc stage1_tile.inc stage2_tile.inc
all: $(NAME)

View File

@ -13,6 +13,10 @@
#include <time.h>
#include <timespec.h>
#define STAGES 2
enum game_mode { TITLESCREEN, STAGE };
enum game_mode game_mode = TITLESCREEN;
#define PLAYFIELD_SIDE 100
#define TILE_SIDE 10
#define TILES (PLAYFIELD_SIDE / TILE_SIDE)
@ -28,11 +32,13 @@ enum palette {
};
static enum palette playfield[PLAYFIELD_SIDE * PLAYFIELD_SIDE];
#include "grass_tile.inc"
#include "dirt_tile.inc"
#include "flag_tile.inc"
#include "stage1_tile.inc"
#include "stage2_tile.inc"
static char tilemap[] = " "
" "
" "
@ -42,7 +48,7 @@ static char tilemap[] = " "
" g "
" g "
"@ gdg "
"ggggdddggg";
"gg dddgg ";
static uint32_t main_window = 0;
static uint32_t window_width = 600;
@ -57,7 +63,6 @@ static void on_disconnect(void *context) {
static bool left_held, right_held, jump_held;
static double jump_maxhold = 0.3;
static double jump_maxheight = 21;
static double jump_duration = 0.4;
@ -115,7 +120,7 @@ static double in_jump;
static double player_x, player_y;
static double player_dx, player_dy;
static void initialize(void) {
static void initialize_stage(void) {
jumping = false;
on_ground = false;
player_dx = 0;
@ -131,7 +136,19 @@ static void initialize(void) {
}
}
static void update(struct timespec now, struct timespec dt_timespec) {
static size_t selection_index = 0;
static bool keys_released;
static bool stage_selected;
static void initialize(void) {
switch (game_mode) {
case TITLESCREEN: keys_released = false; stage_selected = false; break;
case STAGE: initialize_stage(); break;
default: printf("%i\n", game_mode); break;
}
}
static void update_stage(struct timespec now, struct timespec dt_timespec) {
(void) now;
double dt = timespec2double(dt_timespec);
player_x += player_dx * dt;
@ -140,7 +157,6 @@ static void update(struct timespec now, struct timespec dt_timespec) {
else if (right_held) player_dx = 30;
else player_dx = 0;
(void) jump_maxhold;
if (on_ground && jump_held && !jumping) {
jumping = true;
in_jump = 0;
@ -200,6 +216,9 @@ static void update(struct timespec now, struct timespec dt_timespec) {
} else if (player_y > PLAYFIELD_SIDE - TILE_SIDE) {
player_y = PLAYFIELD_SIDE - TILE_SIDE;
player_dy = 0;
game_mode = TITLESCREEN;
initialize();
return;
}
// Collision against tiles
@ -251,6 +270,33 @@ static void update(struct timespec now, struct timespec dt_timespec) {
}
}
static void update_titlescreen(struct timespec now, struct timespec dt_timespec) {
(void) now;
(void) dt_timespec;
if (keys_released && left_held && selection_index > 0)
selection_index--;
if (keys_released && right_held && selection_index < STAGES - 1)
selection_index++;
if (keys_released && jump_held)
stage_selected = true;
if (!left_held && !right_held && !jump_held)
keys_released = true;
else
keys_released = false;
if (stage_selected && keys_released) {
game_mode = STAGE;
initialize();
}
}
static void update(struct timespec now, struct timespec dt_timespec) {
switch (game_mode) {
case TITLESCREEN: update_titlescreen(now, dt_timespec); break;
case STAGE: update_stage(now, dt_timespec); break;
default: printf("%i\n", game_mode); break;
}
}
static void draw_tile(enum palette tile[], size_t x, size_t y) {
assert(x + TILE_SIDE <= PLAYFIELD_SIDE);
assert(y + TILE_SIDE <= PLAYFIELD_SIDE);
@ -278,12 +324,30 @@ static void draw_tiles(void) {
}
}
static void draw(void) {
static void draw_stage(void) {
memset(playfield, 0, sizeof(playfield));
draw_tiles();
draw_tile(grass_tile, player_x, player_y);
}
static void draw_titlescreen(void) {
memset(playfield, 0, sizeof(playfield));
draw_tile(stage1_tile, 1 * TILE_SIDE, TILE_SIDE);
draw_tile(stage2_tile, 2 * TILE_SIDE, TILE_SIDE);
size_t underline_y = 2 * TILE_SIDE + 1;
size_t underline_x = selection_index * TILE_SIDE + TILE_SIDE + 2;
for (size_t x = 0; x < TILE_SIDE - 4; x++)
playfield[underline_y * PLAYFIELD_SIDE + underline_x + x] = TEXT;
}
static void draw(void) {
switch (game_mode) {
case TITLESCREEN: draw_titlescreen(); break;
case STAGE: draw_stage(); break;
default: printf("%i\n", game_mode); break;
}
}
int main(int argc, char *argv[]) {
struct display_connection *connection = display_connect_default();
if (!connection && errno == ECONNREFUSED)

13
stage1_tile.txt Normal file
View File

@ -0,0 +1,13 @@
xTEXT
.BG
----------
....xx....
...xxx....
..xxxx....
.xx.xx....
....xx....
....xx....
....xx....
....xx....
....xx....
.xxxxxxxx.

13
stage2_tile.txt Normal file
View File

@ -0,0 +1,13 @@
xTEXT
.BG
----------
....xxx...
...xx.xx..
..xx...xx.
......xx..
.....xx...
....xx....
...xx.....
..xx......
.xx.......
.xxxxxxxx.