Initial triangle swap animations (+demote on incorrect answers)

This commit is contained in:
RandyTheSilly committed 2026-11-11 00:10:28 -05:00
1 parent 26dc5f9505
commit 00456f8224
3 files changed
+76 -53

No files matched your search

-7
View File
@@ -58,13 +58,6 @@
"spaceOptimization": "storage", "spaceOptimization": "storage",
"type": "bitmap" "type": "bitmap"
}, },
{
"file": "x.png",
"memoryFormat": "Smallest",
"name": "X",
"spaceOptimization": "storage",
"type": "bitmap"
},
{ {
"file": "check.png", "file": "check.png",
"memoryFormat": "Smallest", "memoryFormat": "Smallest",
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

+76 -46
View File
@@ -23,8 +23,6 @@ static BitmapLayer *s_check_bmp_layer;
static TextLayer *s_setter_txt_layer; static TextLayer *s_setter_txt_layer;
static Layer *s_setter_highlight_layer; static Layer *s_setter_highlight_layer;
//// alarm //// alarm
static BitmapLayer *s_x_bmp_layer;
static Animation *s_x_anim_master;
static Layer *s_graph_layer; static Layer *s_graph_layer;
static TextLayer *s_theta_txt_layer; static TextLayer *s_theta_txt_layer;
static TextLayer *s_parenthesis_txt_layer; static TextLayer *s_parenthesis_txt_layer;
@@ -44,6 +42,8 @@ static TextLayer *s_progress_txt_layer;
static TextLayer *s_side_a_txt_layer; static TextLayer *s_side_a_txt_layer;
static TextLayer *s_side_b_txt_layer; static TextLayer *s_side_b_txt_layer;
static TextLayer *s_side_c_txt_layer; static TextLayer *s_side_c_txt_layer;
static Layer *s_left_door_layer;
static Layer *s_right_door_layer;
// fonts // fonts
GFont s_font_lecoish_small; GFont s_font_lecoish_small;
@@ -57,8 +57,6 @@ GFont s_font_mansalva_small;
//// setter //// setter
static GBitmap *s_clock_bmp; static GBitmap *s_clock_bmp;
static GBitmap *s_check_bmp; static GBitmap *s_check_bmp;
//// alarm
static GBitmap *s_x_bmp;
// global vars // global vars
static WakeupReason s_alarm_reason; static WakeupReason s_alarm_reason;
@@ -91,6 +89,7 @@ static const GColor s_primary_color = GColorJaegerGreen;
#define MAX_SECS_WITHOUT_INPUT 10 #define MAX_SECS_WITHOUT_INPUT 10
#define SHAKE_COOLDOWN_SECS 2 #define SHAKE_COOLDOWN_SECS 2
#define ZAP_COOLDOWN_SECS 4 #define ZAP_COOLDOWN_SECS 4
static const uint8_t s_small_top_bar_height = s_top_bar_grect.size.h / 2;
static const uint8_t s_drop_height = 22; static const uint8_t s_drop_height = 22;
static const GRect s_drop_function_grect = GRect(PBL_IF_ROUND_ELSE(55, 45), s_bottom_bar_grect.origin.y + ((s_bottom_bar_grect.size.h / 2) - PBL_IF_ROUND_ELSE(s_drop_height - 1, s_drop_height / 2)), 50, s_drop_height); static const GRect s_drop_function_grect = GRect(PBL_IF_ROUND_ELSE(55, 45), s_bottom_bar_grect.origin.y + ((s_bottom_bar_grect.size.h / 2) - PBL_IF_ROUND_ELSE(s_drop_height - 1, s_drop_height / 2)), 50, s_drop_height);
static const GRect s_drop_over_grect = GRect(s_drop_function_grect.origin.x + 78, s_drop_function_grect.origin.y - 13, s_drop_function_grect.size.w + 1, s_drop_function_grect.size.h); static const GRect s_drop_over_grect = GRect(s_drop_function_grect.origin.x + 78, s_drop_function_grect.origin.y - 13, s_drop_function_grect.size.w + 1, s_drop_function_grect.size.h);
@@ -107,6 +106,10 @@ static const VibePattern s_first_triangle_vibe_pattern = {
.num_segments = ARRAY_LENGTH(s_first_triangle_vibe_segments), .num_segments = ARRAY_LENGTH(s_first_triangle_vibe_segments),
}; };
// animation stuff
static GRect s_left_door_starting_grect = GRect(-(PBL_DISPLAY_WIDTH / 2), s_small_top_bar_height, PBL_DISPLAY_WIDTH / 2, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h);
static GRect s_right_door_starting_grect = GRect(PBL_DISPLAY_WIDTH, s_small_top_bar_height, PBL_DISPLAY_WIDTH / 2, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h);
// alarm drop menu options // alarm drop menu options
static const char *s_options_function[3]; static const char *s_options_function[3];
static char *s_options_over[2]; static char *s_options_over[2];
@@ -371,7 +374,8 @@ static void set_alarm_highlighter_frame() {
} }
} }
static void clear_selections() { static void update_for_new_triangle() {
// clear selections
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
s_selected_indices[i] = 9; s_selected_indices[i] = 9;
} }
@@ -380,10 +384,6 @@ static void clear_selections() {
text_layer_set_text(s_drop_txt_function_layer, ""); text_layer_set_text(s_drop_txt_function_layer, "");
text_layer_set_text(s_drop_txt_over_layer, ""); text_layer_set_text(s_drop_txt_over_layer, "");
text_layer_set_text(s_drop_txt_under_layer, ""); text_layer_set_text(s_drop_txt_under_layer, "");
}
static void update_for_new_triangle() {
clear_selections();
// pick & display 2 side lengths to the user // pick & display 2 side lengths to the user
static char side_a_buffer[8], side_b_buffer[8], side_c_buffer[8]; static char side_a_buffer[8], side_b_buffer[8], side_c_buffer[8];
@@ -505,6 +505,65 @@ static void update_for_new_triangle() {
text_layer_set_text(s_progress_txt_layer, s_progress_buf); text_layer_set_text(s_progress_txt_layer, s_progress_buf);
} }
static void door_layer_red_update_proc(Layer *layer, GContext *ctx) {
graphics_context_set_fill_color(ctx, GColorMelon);
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
}
static void door_layer_green_update_proc(Layer *layer, GContext *ctx) {
graphics_context_set_fill_color(ctx, GColorMediumAquamarine);
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
}
static void door_closed_fail_animation_handler(Animation *animation, bool finished, void *context) {
if (s_current_triangle_num > 1) {
s_current_triangle_num--;
}
right_triangle_layer_regen(s_triangle_layer);
update_for_new_triangle();
}
static void door_closed_success_animation_handler(Animation *animation, bool finished, void *context) {
s_current_triangle_num++;
right_triangle_layer_regen(s_triangle_layer);
update_for_new_triangle();
}
static void destroy_animation_handler(Animation *animation, bool finished, void *context) {
animation_destroy(animation);
}
// TODO:
// reuse some of these animations, if possible
// add iconography to door halves
static void play_door_animation(bool correct) {
PropertyAnimation *left_door_prop_anim = property_animation_create_layer_frame(s_left_door_layer, &s_left_door_starting_grect, &GRect(0, s_left_door_starting_grect.origin.y, s_left_door_starting_grect.size.w, s_left_door_starting_grect.size.h));
PropertyAnimation *right_door_prop_anim = property_animation_create_layer_frame(s_right_door_layer, &s_right_door_starting_grect, &GRect(PBL_DISPLAY_WIDTH / 2, s_left_door_starting_grect.origin.y, s_left_door_starting_grect.size.w, s_left_door_starting_grect.size.h));
Animation *left_door_close_anim = property_animation_get_animation(left_door_prop_anim);
Animation *right_door_close_anim = property_animation_get_animation(right_door_prop_anim);
animation_set_duration(left_door_close_anim, 500);
animation_set_duration(right_door_close_anim, 500);
Animation *left_door_open_anim = animation_clone(left_door_close_anim);
Animation *right_door_open_anim = animation_clone(right_door_close_anim);
animation_set_reverse(left_door_open_anim, true);
animation_set_reverse(right_door_open_anim, true);
Animation *door_close_spawn_anim = animation_spawn_create(left_door_close_anim, right_door_close_anim, NULL);
Animation *door_open_spawn_anim = animation_spawn_create(left_door_open_anim, right_door_open_anim, NULL);
animation_set_delay(door_open_spawn_anim, 100);
if (correct) {
layer_set_update_proc(s_left_door_layer, door_layer_green_update_proc);
layer_set_update_proc(s_right_door_layer, door_layer_green_update_proc);
animation_set_handlers(door_close_spawn_anim, (AnimationHandlers){.stopped = door_closed_success_animation_handler}, NULL);
} else {
layer_set_update_proc(s_left_door_layer, door_layer_red_update_proc);
layer_set_update_proc(s_right_door_layer, door_layer_red_update_proc);
animation_set_handlers(door_close_spawn_anim, (AnimationHandlers){.stopped = door_closed_fail_animation_handler}, NULL);
}
Animation *seq = animation_sequence_create(door_close_spawn_anim, door_open_spawn_anim, NULL);
animation_set_handlers(seq, (AnimationHandlers){.stopped = destroy_animation_handler}, NULL);
animation_schedule(seq);
};
static void increment_secs_since_last_input() { static void increment_secs_since_last_input() {
if (s_secs_since_last_input < MAX_SECS_WITHOUT_INPUT) { if (s_secs_since_last_input < MAX_SECS_WITHOUT_INPUT) {
s_secs_since_last_input++; s_secs_since_last_input++;
@@ -536,12 +595,8 @@ static void alarm_tick_handler(struct tm *tick_time, TimeUnits units_changed) {
if (s_countdown_int == 0) { if (s_countdown_int == 0) {
s_continuous_zap_on_first_triangle = true; // begin zapping once the first countdown expires s_continuous_zap_on_first_triangle = true; // begin zapping once the first countdown expires
send_zap(); send_zap();
if (s_current_triangle_num > 1) {
s_current_triangle_num--;
}
s_secs_since_last_input = 10; s_secs_since_last_input = 10;
right_triangle_layer_regen(s_triangle_layer); play_door_animation(false);
update_for_new_triangle();
} }
// minutes // minutes
@@ -612,8 +667,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) {
// check solution // check solution
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (s_selected_indices[i] != s_solution_indices[i]) { if (s_selected_indices[i] != s_solution_indices[i]) {
animation_schedule(animation_clone(s_x_anim_master)); play_door_animation(false);
clear_selections();
return; return;
} }
} }
@@ -626,9 +680,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) {
push_status_window(STATUS_CONFIRMATION); push_status_window(STATUS_CONFIRMATION);
} }
} else { } else {
s_current_triangle_num++; play_door_animation(true);
right_triangle_layer_regen(s_triangle_layer);
update_for_new_triangle();
} }
} }
@@ -705,16 +757,6 @@ static void live_wakeup_handler_for_alarm(WakeupId id, int32_t wakeup_reason) {
} }
} }
static void anim_handler_flash_x_start(Animation *animation, void *context) {
layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), false);
}
static void anim_handler_flash_x_end(Animation *animation, bool finished, void *context) {
layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), true);
animation_destroy(animation);
}
static void anim_update_flash_x(Animation *animation, const AnimationProgress progress) {} // dummy
static const AnimationImplementation s_x_anim_impl = {.update = anim_update_flash_x};
static void alarm_window_load() { static void alarm_window_load() {
wakeup_service_subscribe(live_wakeup_handler_for_alarm); wakeup_service_subscribe(live_wakeup_handler_for_alarm);
@@ -795,7 +837,6 @@ static void alarm_window_load() {
layer_add_child(window_layer, s_alarm_highlight_layer); layer_add_child(window_layer, s_alarm_highlight_layer);
// triangle // triangle
static const uint8_t s_small_top_bar_height = s_top_bar_grect.size.h / 2;
s_triangle_layer = right_triangle_layer_create(GRect(0, s_small_top_bar_height, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h), GColorBlack); s_triangle_layer = right_triangle_layer_create(GRect(0, s_small_top_bar_height, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT - s_small_top_bar_height - s_bottom_bar_grect.size.h), GColorBlack);
layer_add_child(window_layer, s_triangle_layer->layer); layer_add_child(window_layer, s_triangle_layer->layer);
@@ -850,19 +891,11 @@ static void alarm_window_load() {
text_layer_set_font(s_progress_txt_layer, fonts_get_system_font(FONT_KEY_LECO_20_BOLD_NUMBERS)); text_layer_set_font(s_progress_txt_layer, fonts_get_system_font(FONT_KEY_LECO_20_BOLD_NUMBERS));
layer_add_child(window_layer, text_layer_get_layer(s_progress_txt_layer)); layer_add_child(window_layer, text_layer_get_layer(s_progress_txt_layer));
// x (incorrect equation icon) // door layers
s_x_bmp = gbitmap_create_with_resource(RESOURCE_ID_X); s_left_door_layer = layer_create(s_left_door_starting_grect);
s_x_bmp_layer = bitmap_layer_create(GRect(20, 24, 160, 179)); s_right_door_layer = layer_create(s_right_door_starting_grect);
bitmap_layer_set_bitmap(s_x_bmp_layer, s_x_bmp); layer_add_child(window_layer, s_left_door_layer);
bitmap_layer_set_compositing_mode(s_x_bmp_layer, GCompOpSet); layer_add_child(window_layer, s_right_door_layer);
layer_set_hidden(bitmap_layer_get_layer(s_x_bmp_layer), true); // hide until needed
layer_add_child(window_layer, bitmap_layer_get_layer(s_x_bmp_layer));
// x flash animation init
s_x_anim_master = animation_create();
animation_set_implementation(s_x_anim_master, &s_x_anim_impl);
animation_set_duration(s_x_anim_master, 1500);
animation_set_handlers(s_x_anim_master, (AnimationHandlers){.started = anim_handler_flash_x_start, .stopped = anim_handler_flash_x_end}, NULL);
// configure UI around current triangle in s_triangle_layer // configure UI around current triangle in s_triangle_layer
s_current_triangle_num = 1; s_current_triangle_num = 1;
@@ -880,9 +913,6 @@ static void alarm_window_load() {
static void alarm_window_unload() { static void alarm_window_unload() {
tick_timer_service_unsubscribe(); tick_timer_service_unsubscribe();
accel_tap_service_unsubscribe(); accel_tap_service_unsubscribe();
animation_destroy(s_x_anim_master);
gbitmap_destroy(s_x_bmp);
bitmap_layer_destroy(s_x_bmp_layer);
text_layer_destroy(s_progress_txt_layer); text_layer_destroy(s_progress_txt_layer);
text_layer_destroy(s_countdown_txt_layer); text_layer_destroy(s_countdown_txt_layer);
window_destroy(s_drop_window); window_destroy(s_drop_window);