2 Commits
2 changed files with 61 additions and 12 deletions
+2
View File
@@ -2,6 +2,8 @@
#include "internal/engine_internal.h"
#include <stdlib.h>
engine_internal_state_t *internal_state = NULL;
game_state_t *game_state = NULL;
+59 -12
View File
@@ -28,6 +28,14 @@ typedef struct {
int col;
} line_tile_t;
typedef enum {
GAME_PLAYING,
GAME_WON,
GAME_LOST
} game_status_t;
static game_status_t game_status;
typedef struct {
uint32_t area[SIZE][SIZE];
dir_e direction;
@@ -42,6 +50,17 @@ static size_t move_track_count;
static double last_frame_time;
static bool
board_is_full(void)
{
for (int r = 0; r < SIZE; ++r)
for (int c = 0; c < SIZE; ++c)
if (game.area[r][c] == 0)
return false;
return true;
}
/* Pixel size is calculated from the current window size while drawing. */
static uint32_t
colors(uint32_t number)
@@ -151,6 +170,8 @@ process_line(dir_e direction, int line, uint32_t output[SIZE])
if (i + 1 < input_count &&
input[i].value == input[i + 1].value) {
uint32_t merged_value = input[i].value * 2;
if (merged_value >= 2048)
game_status = GAME_WON;
output[output_count] = merged_value;
game.score += merged_value;
@@ -194,6 +215,9 @@ process_line(dir_e direction, int line, uint32_t output[SIZE])
static bool
slide(dir_e direction)
{
if (game_status != GAME_PLAYING || anim_is_active(&movement))
return false;
if (anim_is_active(&movement))
return false;
@@ -260,16 +284,20 @@ client_poll_event(void)
game_state->is_running = false;
break;
case SDLK_W:
slide(UP);
if (game_status == GAME_PLAYING)
slide(UP);
break;
case SDLK_S:
slide(DOWN);
if (game_status == GAME_PLAYING)
slide(DOWN);
break;
case SDLK_A:
slide(LEFT);
if (game_status == GAME_PLAYING)
slide(LEFT);
break;
case SDLK_D:
slide(RIGHT);
if (game_status == GAME_PLAYING)
slide(RIGHT);
break;
default:
break;
@@ -324,7 +352,12 @@ client_update_framebuffer(void)
dt = 0.05f;
if (anim_is_active(&movement) && anim_update(&movement, dt)) {
new_2();
if (game_status == GAME_PLAYING) {
new_2();
if (board_is_full())
game_status = GAME_LOST;
}
}
uint32_t tile_size = game_state->width / SIZE;
@@ -332,7 +365,26 @@ client_update_framebuffer(void)
clear_framebuffer(OVERDRAW, 0x000000);
/* Draw all cell backgrounds first. */
char score_text[32];
snprintf(score_text, sizeof score_text, "score: %u", game.score);
put_string(OVERDRAW, score_text,
border_width / 2, tile_size * SIZE + border_width / 2,
6, 1, 12, 0xFFFFFF, 0x000000);
if (game_status != GAME_PLAYING) {
clear_framebuffer(BASE, 0x000000);
const char *message =
game_status == GAME_WON ? "YOU WIN!" : "YOU LOSE!";
put_string(OVERDRAW, message,
0 + border_width * 2,
game_state->height / 2,
6, 1, 12, 0xFFFFFF, 0x000000);
return;
}
/* Draw all cell backgrounds. */
for (int r = 0; r < SIZE; ++r) {
for (int c = 0; c < SIZE; ++c) {
uint32_t x = border_width / 2 + (uint32_t)c * tile_size;
@@ -360,17 +412,12 @@ client_update_framebuffer(void)
}
}
}
char score_text[32];
snprintf(score_text, sizeof score_text, "score: %u", game.score);
put_string(OVERDRAW, score_text,
border_width / 2, tile_size * SIZE + border_width / 2,
6, 1, 12, 0xFFFFFF, 0x000000);
}
static void
game_init(void)
{
game_status = GAME_PLAYING;
memset(&game, 0, sizeof game);
anim_init(&movement);
srand((unsigned)time(NULL));