138 lines
3.5 KiB
C
138 lines
3.5 KiB
C
#include "apps.h"
|
|
#include "os_gfx.h"
|
|
#include "os_status.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define GROUND_Y 34
|
|
|
|
typedef enum {
|
|
GAME_STATE_READY,
|
|
GAME_STATE_PLAYING,
|
|
GAME_STATE_OVER
|
|
} game_state_t;
|
|
|
|
static game_state_t s_game_state = GAME_STATE_READY;
|
|
static int16_t s_player_y = GROUND_Y;
|
|
static int16_t s_player_vy = 0;
|
|
static bool s_is_jumping = false;
|
|
|
|
static int16_t s_obs_x = 72;
|
|
static int16_t s_obs_h = 6;
|
|
static uint16_t s_score = 0;
|
|
static uint16_t s_high_score = 0;
|
|
|
|
static void game_reset(void)
|
|
{
|
|
s_player_y = GROUND_Y;
|
|
s_player_vy = 0;
|
|
s_is_jumping = false;
|
|
s_obs_x = 72;
|
|
s_obs_h = 5 + (rand() % 4);
|
|
s_score = 0;
|
|
}
|
|
|
|
static void game_init(void)
|
|
{
|
|
s_game_state = GAME_STATE_READY;
|
|
s_high_score = 0;
|
|
game_reset();
|
|
}
|
|
|
|
static void game_enter(void)
|
|
{
|
|
s_game_state = GAME_STATE_READY;
|
|
game_reset();
|
|
}
|
|
|
|
static void game_update(uint32_t delta_ms)
|
|
{
|
|
sys_gfx_draw_line(0, GROUND_Y + 1, OLED_WIDTH - 1, GROUND_Y + 1, COLOR_WHITE);
|
|
|
|
if (s_game_state == GAME_STATE_READY) {
|
|
sys_gfx_draw_str_5x7(10, 8, "TINY JUMP", COLOR_WHITE);
|
|
sys_gfx_draw_str_3x5(8, 20, "CLICK TO START", COLOR_WHITE);
|
|
sys_gfx_draw_action_bar("C:JUMP", "H:HOME");
|
|
sys_gfx_fill_rect(8, GROUND_Y - 5, 5, 5, COLOR_WHITE);
|
|
return;
|
|
}
|
|
|
|
if (s_game_state == GAME_STATE_PLAYING) {
|
|
if (s_is_jumping) {
|
|
s_player_y += s_player_vy;
|
|
s_player_vy += 1;
|
|
if (s_player_y >= GROUND_Y) {
|
|
s_player_y = GROUND_Y;
|
|
s_player_vy = 0;
|
|
s_is_jumping = false;
|
|
}
|
|
}
|
|
|
|
s_obs_x -= 3;
|
|
if (s_obs_x < -4) {
|
|
s_obs_x = 72 + (rand() % 16);
|
|
s_obs_h = 5 + (rand() % 5);
|
|
s_score++;
|
|
if (s_score > s_high_score) s_high_score = s_score;
|
|
}
|
|
|
|
if (s_obs_x <= 13 && (s_obs_x + 3) >= 8) {
|
|
if ((s_player_y - 1) >= (GROUND_Y - s_obs_h + 1)) {
|
|
s_game_state = GAME_STATE_OVER;
|
|
sys_gfx_show_toast("GAME OVER", 800);
|
|
}
|
|
}
|
|
|
|
sys_gfx_fill_rect(8, s_player_y - 5, 5, 5, COLOR_WHITE);
|
|
sys_gfx_fill_rect(s_obs_x, GROUND_Y - s_obs_h + 1, 3, s_obs_h, COLOR_WHITE);
|
|
|
|
char score_str[12];
|
|
snprintf(score_str, sizeof(score_str), "SC:%u", s_score);
|
|
sys_gfx_draw_str_3x5(45, 1, score_str, COLOR_WHITE);
|
|
|
|
} else if (s_game_state == GAME_STATE_OVER) {
|
|
sys_gfx_draw_str_5x7(12, 6, "GAME OVER", COLOR_WHITE);
|
|
|
|
char buf[16];
|
|
snprintf(buf, sizeof(buf), "SCORE: %u", s_score);
|
|
sys_gfx_draw_str_3x5(16, 17, buf, COLOR_WHITE);
|
|
|
|
snprintf(buf, sizeof(buf), "BEST: %u", s_high_score);
|
|
sys_gfx_draw_str_3x5(16, 24, buf, COLOR_WHITE);
|
|
|
|
sys_gfx_draw_action_bar("C:RESTART", "H:HOME");
|
|
}
|
|
}
|
|
|
|
static void game_handle_input(input_action_t action)
|
|
{
|
|
if (action == INPUT_ACTION_CLICK) {
|
|
if (s_game_state == GAME_STATE_READY) {
|
|
s_game_state = GAME_STATE_PLAYING;
|
|
game_reset();
|
|
} else if (s_game_state == GAME_STATE_PLAYING) {
|
|
if (!s_is_jumping) {
|
|
s_is_jumping = true;
|
|
s_player_vy = -5;
|
|
}
|
|
} else if (s_game_state == GAME_STATE_OVER) {
|
|
s_game_state = GAME_STATE_PLAYING;
|
|
game_reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void game_exit(void)
|
|
{
|
|
}
|
|
|
|
const sys_app_t g_app_game = {
|
|
.id = "game",
|
|
.name = "Tiny Jump",
|
|
.init = game_init,
|
|
.enter = game_enter,
|
|
.update = game_update,
|
|
.handle_input = game_handle_input,
|
|
.exit = game_exit,
|
|
};
|