diff --git a/Makefile b/Makefile index 07435cc..d8d4b09 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/platformer.c b/platformer.c index cc04753..34d649c 100644 --- a/platformer.c +++ b/platformer.c @@ -13,6 +13,10 @@ #include #include +#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) diff --git a/stage1_tile.txt b/stage1_tile.txt new file mode 100644 index 0000000..b84d02d --- /dev/null +++ b/stage1_tile.txt @@ -0,0 +1,13 @@ +xTEXT +.BG +---------- +....xx.... +...xxx.... +..xxxx.... +.xx.xx.... +....xx.... +....xx.... +....xx.... +....xx.... +....xx.... +.xxxxxxxx. diff --git a/stage2_tile.txt b/stage2_tile.txt new file mode 100644 index 0000000..6e18e0c --- /dev/null +++ b/stage2_tile.txt @@ -0,0 +1,13 @@ +xTEXT +.BG +---------- +....xxx... +...xx.xx.. +..xx...xx. +......xx.. +.....xx... +....xx.... +...xx..... +..xx...... +.xx....... +.xxxxxxxx.