Initial triangle swap animations (+demote on incorrect answers)
This commit is contained in:
1 parent
26dc5f9505
commit
00456f8224
3 files changed
+76
-53
No files matched your search
@@ -58,13 +58,6 @@
|
||||
"spaceOptimization": "storage",
|
||||
"type": "bitmap"
|
||||
},
|
||||
{
|
||||
"file": "x.png",
|
||||
"memoryFormat": "Smallest",
|
||||
"name": "X",
|
||||
"spaceOptimization": "storage",
|
||||
"type": "bitmap"
|
||||
},
|
||||
{
|
||||
"file": "check.png",
|
||||
"memoryFormat": "Smallest",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.0 KiB |
+76
-46
@@ -23,8 +23,6 @@ static BitmapLayer *s_check_bmp_layer;
|
||||
static TextLayer *s_setter_txt_layer;
|
||||
static Layer *s_setter_highlight_layer;
|
||||
//// alarm
|
||||
static BitmapLayer *s_x_bmp_layer;
|
||||
static Animation *s_x_anim_master;
|
||||
static Layer *s_graph_layer;
|
||||
static TextLayer *s_theta_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_b_txt_layer;
|
||||
static TextLayer *s_side_c_txt_layer;
|
||||
static Layer *s_left_door_layer;
|
||||
static Layer *s_right_door_layer;
|
||||
|
||||
// fonts
|
||||
GFont s_font_lecoish_small;
|
||||
@@ -57,8 +57,6 @@ GFont s_font_mansalva_small;
|
||||
//// setter
|
||||
static GBitmap *s_clock_bmp;
|
||||
static GBitmap *s_check_bmp;
|
||||
//// alarm
|
||||
static GBitmap *s_x_bmp;
|
||||
|
||||
// global vars
|
||||
static WakeupReason s_alarm_reason;
|
||||
@@ -91,6 +89,7 @@ static const GColor s_primary_color = GColorJaegerGreen;
|
||||
#define MAX_SECS_WITHOUT_INPUT 10
|
||||
#define SHAKE_COOLDOWN_SECS 2
|
||||
#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 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);
|
||||
@@ -107,6 +106,10 @@ static const VibePattern s_first_triangle_vibe_pattern = {
|
||||
.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
|
||||
static const char *s_options_function[3];
|
||||
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) {
|
||||
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_over_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
|
||||
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);
|
||||
}
|
||||
|
||||
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() {
|
||||
if (s_secs_since_last_input < MAX_SECS_WITHOUT_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) {
|
||||
s_continuous_zap_on_first_triangle = true; // begin zapping once the first countdown expires
|
||||
send_zap();
|
||||
if (s_current_triangle_num > 1) {
|
||||
s_current_triangle_num--;
|
||||
}
|
||||
s_secs_since_last_input = 10;
|
||||
right_triangle_layer_regen(s_triangle_layer);
|
||||
update_for_new_triangle();
|
||||
play_door_animation(false);
|
||||
}
|
||||
|
||||
// minutes
|
||||
@@ -612,8 +667,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) {
|
||||
// check solution
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (s_selected_indices[i] != s_solution_indices[i]) {
|
||||
animation_schedule(animation_clone(s_x_anim_master));
|
||||
clear_selections();
|
||||
play_door_animation(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -626,9 +680,7 @@ static void accel_tap_handler(AccelAxisType axis, int32_t direction) {
|
||||
push_status_window(STATUS_CONFIRMATION);
|
||||
}
|
||||
} else {
|
||||
s_current_triangle_num++;
|
||||
right_triangle_layer_regen(s_triangle_layer);
|
||||
update_for_new_triangle();
|
||||
play_door_animation(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
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);
|
||||
|
||||
// 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);
|
||||
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));
|
||||
layer_add_child(window_layer, text_layer_get_layer(s_progress_txt_layer));
|
||||
|
||||
// x (incorrect equation icon)
|
||||
s_x_bmp = gbitmap_create_with_resource(RESOURCE_ID_X);
|
||||
s_x_bmp_layer = bitmap_layer_create(GRect(20, 24, 160, 179));
|
||||
bitmap_layer_set_bitmap(s_x_bmp_layer, s_x_bmp);
|
||||
bitmap_layer_set_compositing_mode(s_x_bmp_layer, GCompOpSet);
|
||||
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);
|
||||
// door layers
|
||||
s_left_door_layer = layer_create(s_left_door_starting_grect);
|
||||
s_right_door_layer = layer_create(s_right_door_starting_grect);
|
||||
layer_add_child(window_layer, s_left_door_layer);
|
||||
layer_add_child(window_layer, s_right_door_layer);
|
||||
|
||||
// configure UI around current triangle in s_triangle_layer
|
||||
s_current_triangle_num = 1;
|
||||
@@ -880,9 +913,6 @@ static void alarm_window_load() {
|
||||
static void alarm_window_unload() {
|
||||
tick_timer_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_countdown_txt_layer);
|
||||
window_destroy(s_drop_window);
|
||||
|
||||
Reference in new issue
Block a user