Compare commits
3
Commits
dcd3ed9245
..
v0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f367ef48a8 | ||
|
|
0dafe93b51 | ||
|
|
a14bd280ff |
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "internal/engine_internal.h"
|
#include "internal/engine_internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
engine_internal_state_t *internal_state = NULL;
|
engine_internal_state_t *internal_state = NULL;
|
||||||
game_state_t *game_state = NULL;
|
game_state_t *game_state = NULL;
|
||||||
|
|
||||||
|
|||||||
+63
-12
@@ -28,6 +28,14 @@ typedef struct {
|
|||||||
int col;
|
int col;
|
||||||
} line_tile_t;
|
} line_tile_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GAME_PLAYING,
|
||||||
|
GAME_WON,
|
||||||
|
GAME_LOST
|
||||||
|
} game_status_t;
|
||||||
|
|
||||||
|
static game_status_t game_status;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t area[SIZE][SIZE];
|
uint32_t area[SIZE][SIZE];
|
||||||
dir_e direction;
|
dir_e direction;
|
||||||
@@ -42,6 +50,17 @@ static size_t move_track_count;
|
|||||||
|
|
||||||
static double last_frame_time;
|
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. */
|
/* Pixel size is calculated from the current window size while drawing. */
|
||||||
static uint32_t
|
static uint32_t
|
||||||
colors(uint32_t number)
|
colors(uint32_t number)
|
||||||
@@ -151,6 +170,8 @@ process_line(dir_e direction, int line, uint32_t output[SIZE])
|
|||||||
if (i + 1 < input_count &&
|
if (i + 1 < input_count &&
|
||||||
input[i].value == input[i + 1].value) {
|
input[i].value == input[i + 1].value) {
|
||||||
uint32_t merged_value = input[i].value * 2;
|
uint32_t merged_value = input[i].value * 2;
|
||||||
|
if (merged_value >= 2048)
|
||||||
|
game_status = GAME_WON;
|
||||||
|
|
||||||
output[output_count] = merged_value;
|
output[output_count] = merged_value;
|
||||||
game.score += merged_value;
|
game.score += merged_value;
|
||||||
@@ -194,6 +215,9 @@ process_line(dir_e direction, int line, uint32_t output[SIZE])
|
|||||||
static bool
|
static bool
|
||||||
slide(dir_e direction)
|
slide(dir_e direction)
|
||||||
{
|
{
|
||||||
|
if (game_status != GAME_PLAYING || anim_is_active(&movement))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (anim_is_active(&movement))
|
if (anim_is_active(&movement))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -260,16 +284,24 @@ client_poll_event(void)
|
|||||||
game_state->is_running = false;
|
game_state->is_running = false;
|
||||||
break;
|
break;
|
||||||
case SDLK_W:
|
case SDLK_W:
|
||||||
slide(UP);
|
case SDLK_UP:
|
||||||
|
if (game_status == GAME_PLAYING)
|
||||||
|
slide(UP);
|
||||||
break;
|
break;
|
||||||
case SDLK_S:
|
case SDLK_S:
|
||||||
slide(DOWN);
|
case SDLK_DOWN:
|
||||||
|
if (game_status == GAME_PLAYING)
|
||||||
|
slide(DOWN);
|
||||||
break;
|
break;
|
||||||
case SDLK_A:
|
case SDLK_A:
|
||||||
slide(LEFT);
|
case SDLK_LEFT:
|
||||||
|
if (game_status == GAME_PLAYING)
|
||||||
|
slide(LEFT);
|
||||||
break;
|
break;
|
||||||
case SDLK_D:
|
case SDLK_D:
|
||||||
slide(RIGHT);
|
case SDLK_RIGHT:
|
||||||
|
if (game_status == GAME_PLAYING)
|
||||||
|
slide(RIGHT);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -324,7 +356,12 @@ client_update_framebuffer(void)
|
|||||||
dt = 0.05f;
|
dt = 0.05f;
|
||||||
|
|
||||||
if (anim_is_active(&movement) && anim_update(&movement, dt)) {
|
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;
|
uint32_t tile_size = game_state->width / SIZE;
|
||||||
@@ -332,7 +369,26 @@ client_update_framebuffer(void)
|
|||||||
|
|
||||||
clear_framebuffer(OVERDRAW, 0x000000);
|
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 r = 0; r < SIZE; ++r) {
|
||||||
for (int c = 0; c < SIZE; ++c) {
|
for (int c = 0; c < SIZE; ++c) {
|
||||||
uint32_t x = border_width / 2 + (uint32_t)c * tile_size;
|
uint32_t x = border_width / 2 + (uint32_t)c * tile_size;
|
||||||
@@ -360,17 +416,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
|
static void
|
||||||
game_init(void)
|
game_init(void)
|
||||||
{
|
{
|
||||||
|
game_status = GAME_PLAYING;
|
||||||
memset(&game, 0, sizeof game);
|
memset(&game, 0, sizeof game);
|
||||||
anim_init(&movement);
|
anim_init(&movement);
|
||||||
srand((unsigned)time(NULL));
|
srand((unsigned)time(NULL));
|
||||||
|
|||||||
Reference in New Issue
Block a user