Refectored the state machine
This commit is contained in:
parent
07d2bc91a5
commit
6ec6476d0f
@ -40,21 +40,21 @@ typedef enum {
|
|||||||
} RunnerCurrScreen;
|
} RunnerCurrScreen;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DIFF_BABY = 0, // 0.5x speed; 4 0's min; jump is 3 frames
|
DIFF_BABY = 0, // FREQ_SLOW FPS; MIN_ZEROES 0's min; Jump is JUMP_FRAMES_EASY frames
|
||||||
DIFF_EASY, // 1x speed; 4 0's min; jump is 3 frames
|
DIFF_EASY, // FREQ FPS; MIN_ZEROES 0's min; Jump is JUMP_FRAMES_EASY frames
|
||||||
DIFF_NORM, // 1x speed; 4 0's min; jump is 2 frames
|
DIFF_NORM, // FREQ FPS; MIN_ZEROES 0's min; Jump is JUMP_FRAMES frames
|
||||||
DIFF_HARD, // 1x speed; 3 0's min; jump is 2 frames
|
DIFF_HARD, // FREQ FPS; MIN_ZEROES_HARD 0's min; jump is JUMP_FRAMES frames
|
||||||
DIFF_COUNT
|
DIFF_COUNT
|
||||||
} RunnerDifficulty;
|
} RunnerDifficulty;
|
||||||
|
|
||||||
#define NUM_GRID 12
|
#define NUM_GRID 12 // This the length that the obstacle track can be on
|
||||||
#define FREQ 8
|
#define FREQ 8 // Frequency request for the game
|
||||||
#define FREQ_SLOW 4
|
#define FREQ_SLOW 4 // Frequency request for baby mode
|
||||||
#define JUMP_FRAMES 2
|
#define JUMP_FRAMES 2 // Wait this many frames on difficulties above EASY before coming down from the jump button pressed
|
||||||
#define JUMP_FRAMES_EASY 3
|
#define JUMP_FRAMES_EASY 3 // Wait this many frames on difficulties at or below EASY before coming down from the jump button pressed
|
||||||
#define MIN_ZEROES 4
|
#define MIN_ZEROES 4 // At minimum, we'll have this many spaces between obstacles
|
||||||
#define MIN_ZEROES_HARD 3
|
#define MIN_ZEROES_HARD 3 // At minimum, we'll have this many spaces between obstacles on hard mode
|
||||||
#define MAX_HI_SCORE 999
|
#define MAX_HI_SCORE 999 // Max hi score to store and display on the title screen.
|
||||||
#define MAX_DISP_SCORE 39 // The top-right digits can't properly display above 39
|
#define MAX_DISP_SCORE 39 // The top-right digits can't properly display above 39
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -141,6 +141,19 @@ static void display_score(uint8_t score) {
|
|||||||
watch_display_string(buf, 2);
|
watch_display_string(buf, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_and_reset_hi_score(endless_runner_state_t *state) {
|
||||||
|
// Resets the hi scroe at the beginning of each month.
|
||||||
|
watch_date_time date_time = watch_rtc_get_date_time();
|
||||||
|
if ((state -> year_last_hi_score != date_time.unit.year) ||
|
||||||
|
(state -> month_last_hi_score != date_time.unit.month))
|
||||||
|
{
|
||||||
|
// The high score resets itself every new month.
|
||||||
|
state -> hi_score = 0;
|
||||||
|
state -> year_last_hi_score = date_time.unit.year;
|
||||||
|
state -> month_last_hi_score = date_time.unit.month;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void display_difficulty(uint16_t difficulty) {
|
static void display_difficulty(uint16_t difficulty) {
|
||||||
switch (difficulty)
|
switch (difficulty)
|
||||||
{
|
{
|
||||||
@ -160,8 +173,27 @@ static void display_difficulty(uint16_t difficulty) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void change_difficulty(endless_runner_state_t *state) {
|
||||||
|
state -> difficulty = (state -> difficulty + 1) % DIFF_COUNT;
|
||||||
|
display_difficulty(state -> difficulty);
|
||||||
|
if (state -> soundOn) {
|
||||||
|
if (state -> difficulty == 0) watch_buzzer_play_note(BUZZER_NOTE_B4, 30);
|
||||||
|
else watch_buzzer_play_note(BUZZER_NOTE_C5, 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toggle_sound(endless_runner_state_t *state) {
|
||||||
|
state -> soundOn = !state -> soundOn;
|
||||||
|
if (state -> soundOn){
|
||||||
|
watch_buzzer_play_note(BUZZER_NOTE_C5, 30);
|
||||||
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
watch_clear_indicator(WATCH_INDICATOR_BELL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void display_title(endless_runner_state_t *state) {
|
static void display_title(endless_runner_state_t *state) {
|
||||||
char buf[10];
|
|
||||||
uint16_t hi_score = state -> hi_score;
|
uint16_t hi_score = state -> hi_score;
|
||||||
uint8_t difficulty = state -> difficulty;
|
uint8_t difficulty = state -> difficulty;
|
||||||
bool sound_on = state -> soundOn;
|
bool sound_on = state -> soundOn;
|
||||||
@ -169,13 +201,17 @@ static void display_title(endless_runner_state_t *state) {
|
|||||||
game_state.sec_before_moves = 1; // The first obstacles will all be 0s, which is about an extra second of delay.
|
game_state.sec_before_moves = 1; // The first obstacles will all be 0s, which is about an extra second of delay.
|
||||||
if (sound_on) game_state.sec_before_moves--; // Start chime is about 1 second
|
if (sound_on) game_state.sec_before_moves--; // Start chime is about 1 second
|
||||||
watch_set_colon();
|
watch_set_colon();
|
||||||
|
if (hi_score > MAX_HI_SCORE) {
|
||||||
|
watch_display_string("ER HS-- ", 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char buf[14];
|
||||||
if (hi_score <= 99)
|
if (hi_score <= 99)
|
||||||
sprintf(buf, "ER HS%2d ", hi_score);
|
sprintf(buf, "ER HS%2d ", hi_score);
|
||||||
else if (hi_score <= MAX_HI_SCORE)
|
else if (hi_score <= MAX_HI_SCORE)
|
||||||
sprintf(buf, "ER HS%3d ", hi_score);
|
sprintf(buf, "ER HS%3d ", hi_score);
|
||||||
else
|
|
||||||
sprintf(buf, "ER HS-- ", hi_score);
|
|
||||||
watch_display_string(buf, 0);
|
watch_display_string(buf, 0);
|
||||||
|
}
|
||||||
display_difficulty(difficulty);
|
display_difficulty(difficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,52 +339,12 @@ static bool display_obstacles(endless_runner_state_t *state) {
|
|||||||
return success_jump;
|
return success_jump;
|
||||||
}
|
}
|
||||||
|
|
||||||
void endless_runner_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) {
|
static void update_game(endless_runner_state_t *state, uint8_t subsecond) {
|
||||||
(void) settings;
|
|
||||||
(void) watch_face_index;
|
|
||||||
if (*context_ptr == NULL) {
|
|
||||||
*context_ptr = malloc(sizeof(endless_runner_state_t));
|
|
||||||
memset(*context_ptr, 0, sizeof(endless_runner_state_t));
|
|
||||||
endless_runner_state_t *state = (endless_runner_state_t *)*context_ptr;
|
|
||||||
state->difficulty = DIFF_NORM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void endless_runner_face_activate(movement_settings_t *settings, void *context) {
|
|
||||||
(void) settings;
|
|
||||||
(void) context;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool endless_runner_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
|
|
||||||
endless_runner_state_t *state = (endless_runner_state_t *)context;
|
|
||||||
bool success_jump = false;
|
bool success_jump = false;
|
||||||
uint8_t curr_jump_frame = 0;
|
uint8_t curr_jump_frame = 0;
|
||||||
watch_date_time date_time;
|
|
||||||
|
|
||||||
switch (event.event_type) {
|
|
||||||
case EVENT_ACTIVATE:
|
|
||||||
date_time = watch_rtc_get_date_time();
|
|
||||||
if ((state -> year_last_hi_score != date_time.unit.year) ||
|
|
||||||
(state -> month_last_hi_score != date_time.unit.month))
|
|
||||||
{
|
|
||||||
// The high score resets itself every new month.
|
|
||||||
state -> hi_score = 0;
|
|
||||||
state -> year_last_hi_score = date_time.unit.year;
|
|
||||||
state -> month_last_hi_score = date_time.unit.month;
|
|
||||||
}
|
|
||||||
if (state -> soundOn) watch_set_indicator(WATCH_INDICATOR_BELL);
|
|
||||||
display_title(state);
|
|
||||||
break;
|
|
||||||
case EVENT_TICK:
|
|
||||||
switch (game_state.curr_screen)
|
|
||||||
{
|
|
||||||
case SCREEN_TITLE:
|
|
||||||
case SCREEN_LOSE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (game_state.sec_before_moves != 0) {
|
if (game_state.sec_before_moves != 0) {
|
||||||
if (event.subsecond == 0) --game_state.sec_before_moves;
|
if (subsecond == 0) --game_state.sec_before_moves;
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
success_jump = display_obstacles(state);
|
success_jump = display_obstacles(state);
|
||||||
switch (game_state.jump_state)
|
switch (game_state.jump_state)
|
||||||
@ -378,6 +374,40 @@ bool endless_runner_face_loop(movement_event_t event, movement_settings_t *setti
|
|||||||
delay_ms(200); // To show the player jumping onto the obstacle before displaying the lose screen.
|
delay_ms(200); // To show the player jumping onto the obstacle before displaying the lose screen.
|
||||||
display_lose_screen(state);
|
display_lose_screen(state);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void endless_runner_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) {
|
||||||
|
(void) settings;
|
||||||
|
(void) watch_face_index;
|
||||||
|
if (*context_ptr == NULL) {
|
||||||
|
*context_ptr = malloc(sizeof(endless_runner_state_t));
|
||||||
|
memset(*context_ptr, 0, sizeof(endless_runner_state_t));
|
||||||
|
endless_runner_state_t *state = (endless_runner_state_t *)*context_ptr;
|
||||||
|
state->difficulty = DIFF_NORM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void endless_runner_face_activate(movement_settings_t *settings, void *context) {
|
||||||
|
(void) settings;
|
||||||
|
(void) context;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool endless_runner_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
|
||||||
|
endless_runner_state_t *state = (endless_runner_state_t *)context;
|
||||||
|
switch (event.event_type) {
|
||||||
|
case EVENT_ACTIVATE:
|
||||||
|
check_and_reset_hi_score(state);
|
||||||
|
if (state -> soundOn) watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
|
display_title(state);
|
||||||
|
break;
|
||||||
|
case EVENT_TICK:
|
||||||
|
switch (game_state.curr_screen)
|
||||||
|
{
|
||||||
|
case SCREEN_TITLE:
|
||||||
|
case SCREEN_LOSE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
update_game(state, event.subsecond);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -389,14 +419,8 @@ bool endless_runner_face_loop(movement_event_t event, movement_settings_t *setti
|
|||||||
display_title(state);
|
display_title(state);
|
||||||
break;
|
break;
|
||||||
case EVENT_LIGHT_LONG_PRESS:
|
case EVENT_LIGHT_LONG_PRESS:
|
||||||
if (game_state.curr_screen == SCREEN_TITLE) {
|
if (game_state.curr_screen == SCREEN_TITLE)
|
||||||
state -> difficulty = (state -> difficulty + 1) % DIFF_COUNT;
|
change_difficulty(state);
|
||||||
display_difficulty(state -> difficulty);
|
|
||||||
if (state -> soundOn) {
|
|
||||||
if (state -> difficulty == 0) watch_buzzer_play_note(BUZZER_NOTE_B4, 30);
|
|
||||||
else watch_buzzer_play_note(BUZZER_NOTE_C5, 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case EVENT_LIGHT_BUTTON_DOWN:
|
case EVENT_LIGHT_BUTTON_DOWN:
|
||||||
case EVENT_ALARM_BUTTON_DOWN:
|
case EVENT_ALARM_BUTTON_DOWN:
|
||||||
@ -407,16 +431,7 @@ bool endless_runner_face_loop(movement_event_t event, movement_settings_t *setti
|
|||||||
break;
|
break;
|
||||||
case EVENT_ALARM_LONG_PRESS:
|
case EVENT_ALARM_LONG_PRESS:
|
||||||
if (game_state.curr_screen != SCREEN_PLAYING)
|
if (game_state.curr_screen != SCREEN_PLAYING)
|
||||||
{
|
toggle_sound(state);
|
||||||
state -> soundOn = !state -> soundOn;
|
|
||||||
if (state -> soundOn){
|
|
||||||
watch_buzzer_play_note(BUZZER_NOTE_C5, 30);
|
|
||||||
watch_set_indicator(WATCH_INDICATOR_BELL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
watch_clear_indicator(WATCH_INDICATOR_BELL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case EVENT_TIMEOUT:
|
case EVENT_TIMEOUT:
|
||||||
movement_move_to_face(0);
|
movement_move_to_face(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user