Use "conveyor" style animation for part swaps

This commit is contained in:
2026-03-28 20:19:48 -04:00
parent 03e6b06c93
commit 68f0bbe95e

View File

@@ -22,13 +22,25 @@ static GBitmap *s_butt;
static GBitmap *s_bt0_icon;
static GBitmap *s_bt1_icon;
// calculate coordinates for silly guy animations
#define part_x_on_screen ((260 - PBL_DISPLAY_WIDTH) / -2)
#define head_y_resting ((260 - PBL_DISPLAY_HEIGHT) / -2)
#define head_y_raised (((260 - PBL_DISPLAY_HEIGHT) / -2) - 15)
#define butt_y_resting (head_y_resting + 145)
#define butt_y_raised (butt_y_resting + 15)
// declare positions for animation stages
static GRect s_guy_head_grect_on_screen_raised;
static GRect s_guy_head_grect_off_screen_raised;
static GRect s_guy_head_grect_on_screen_resting;
static GRect s_guy_butt_grect_on_screen_raised;
static GRect s_guy_butt_grect_off_screen_raised;
static GRect s_guy_butt_grect_on_screen_resting;
// swap animation: a -> b -> c, skip, d -> b -> a
//// head
static GRect s_guy_head_grect_a = GRect(part_x_on_screen, head_y_resting, 260, 115); // on-screen resting
static GRect s_guy_head_grect_b = GRect(part_x_on_screen, head_y_raised, 260, 115); // on-screen raised
static GRect s_guy_head_grect_c = GRect(-260, head_y_raised, 260, 115); // left raised
static GRect s_guy_head_grect_d = GRect(260, head_y_raised, 260, 115); // right raised
//// butt
static GRect s_guy_butt_grect_a = GRect(part_x_on_screen, butt_y_resting, 260, 115); // on-screen resting
static GRect s_guy_butt_grect_b = GRect(part_x_on_screen, butt_y_raised, 260, 115); // on-screen raised
static GRect s_guy_butt_grect_c = GRect(260, butt_y_raised, 260, 115); // right raised
static GRect s_guy_butt_grect_d = GRect(-260, butt_y_raised, 260, 115); // left raised
#if PBL_DISPLAY_WIDTH <= 180
// 8x+20(4-x)+20,
// where x=one_count,
@@ -60,8 +72,10 @@ static GRect s_bt_grect_b;
static uint8_t s_animation_duration = 255;
static Animation *s_head_raise_template;
static Animation *s_head_out_template;
static Animation *s_head_in_template;
static Animation *s_butt_raise_template;
static Animation *s_butt_out_template;
static Animation *s_butt_in_template;
// declare lookup tables
#if PBL_DISPLAY_WIDTH <= 180
@@ -176,12 +190,11 @@ static void update_minute_1() {
text_layer_set_text(s_memory_layer, s_memory_buffer);
}
static void schedule_guy_animation(Animation *raise_tmpl, Animation *out_tmpl, AnimationStoppedHandler out_handler) {
static void schedule_guy_animation(Animation *raise_tmpl, Animation *out_tmpl, Animation *in_tmpl, AnimationStoppedHandler out_handler) {
Animation *raise = animation_clone(raise_tmpl);
Animation *out = animation_clone(out_tmpl);
animation_set_handlers(out, (AnimationHandlers){.stopped = out_handler}, NULL);
Animation *in = animation_clone(out_tmpl);
animation_set_reverse(in, true);
Animation *in = animation_clone(in_tmpl);
Animation *rest = animation_clone(raise_tmpl);
animation_set_reverse(rest, true);
Animation *seq = animation_sequence_create(raise, out, in, rest, NULL);
@@ -209,7 +222,7 @@ static void update_minute_30_out_handler(Animation *animation, bool finished, vo
static void update_minute_30() {
update_minute_1();
schedule_guy_animation(s_butt_raise_template, s_butt_out_template, update_minute_30_out_handler);
schedule_guy_animation(s_butt_raise_template, s_butt_out_template, s_butt_in_template, update_minute_30_out_handler);
}
static void update_minute_60_out_handler(Animation *animation, bool finished, void *context) {
@@ -230,7 +243,7 @@ static void update_minute_60_out_handler(Animation *animation, bool finished, vo
static void update_minute_60() {
update_minute_1();
schedule_guy_animation(s_head_raise_template, s_head_out_template, update_minute_60_out_handler);
schedule_guy_animation(s_head_raise_template, s_head_out_template, s_head_in_template, update_minute_60_out_handler);
}
static void minute_handler(struct tm *tick_time, TimeUnits units_changed) {
@@ -250,20 +263,9 @@ static void time_bar_update_proc(Layer *layer, GContext *ctx) {
// define contents of the Window upon load
static void main_window_load(Window *window) {
// dynamically calculate coordinates for silly guy animations
int8_t part_x_on_screen = (260 - PBL_DISPLAY_WIDTH) / -2;
int8_t head_y_resting = (260 - PBL_DISPLAY_HEIGHT) / -2;
int8_t head_y_rasied = head_y_resting - 15;
s_guy_head_grect_on_screen_raised = GRect(part_x_on_screen, head_y_rasied, 260, 115);
s_guy_head_grect_off_screen_raised = GRect(-PBL_DISPLAY_WIDTH + part_x_on_screen, head_y_rasied, 260, 115);
s_guy_head_grect_on_screen_resting = GRect(part_x_on_screen, head_y_resting, 260, 115);
s_guy_butt_grect_on_screen_raised = GRect(part_x_on_screen, head_y_resting + 180, 260, 115);
s_guy_butt_grect_off_screen_raised = GRect(PBL_DISPLAY_WIDTH + part_x_on_screen, head_y_resting + 160, 260, 115);
s_guy_butt_grect_on_screen_resting = GRect(part_x_on_screen, head_y_resting + 145, 260, 115);
// format silly guy layers
s_guy_head_layer = bitmap_layer_create(s_guy_head_grect_on_screen_resting);
s_guy_butt_layer = bitmap_layer_create(s_guy_butt_grect_on_screen_resting);
s_guy_head_layer = bitmap_layer_create(s_guy_head_grect_a);
s_guy_butt_layer = bitmap_layer_create(s_guy_butt_grect_a);
bitmap_layer_set_compositing_mode(s_guy_head_layer, GCompOpSet);
bitmap_layer_set_alignment(s_guy_head_layer, GAlignLeft);
bitmap_layer_set_bitmap(s_guy_head_layer, s_head);
@@ -288,26 +290,36 @@ static void main_window_load(Window *window) {
layer_add_child(window_layer, text_layer_get_layer(s_memory_layer));
// create animation templates
// butt Raise
PropertyAnimation *butt_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_resting, &s_guy_butt_grect_on_screen_raised);
//// butt raise
PropertyAnimation *butt_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_a, &s_guy_butt_grect_b);
s_butt_raise_template = property_animation_get_animation(butt_raise_prop);
animation_set_curve(s_butt_raise_template, AnimationCurveEaseOut);
animation_set_duration(s_butt_raise_template, s_animation_duration);
// butt Out
PropertyAnimation *butt_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_raised, &s_guy_butt_grect_off_screen_raised);
//// butt out
PropertyAnimation *butt_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_b, &s_guy_butt_grect_c);
s_butt_out_template = property_animation_get_animation(butt_out_prop);
animation_set_curve(s_butt_out_template, AnimationCurveEaseOut);
animation_set_duration(s_butt_out_template, s_animation_duration);
// head Raise
PropertyAnimation *head_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_resting, &s_guy_head_grect_on_screen_raised);
//// butt in
PropertyAnimation *butt_in_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_d, &s_guy_butt_grect_b);
s_butt_in_template = property_animation_get_animation(butt_in_prop);
animation_set_curve(s_butt_in_template, AnimationCurveEaseOut);
animation_set_duration(s_butt_in_template, s_animation_duration);
//// head raise
PropertyAnimation *head_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_a, &s_guy_head_grect_b);
s_head_raise_template = property_animation_get_animation(head_raise_prop);
animation_set_curve(s_head_raise_template, AnimationCurveEaseOut);
animation_set_duration(s_head_raise_template, s_animation_duration);
// head Out
PropertyAnimation *head_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_raised, &s_guy_head_grect_off_screen_raised);
//// head out
PropertyAnimation *head_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_b, &s_guy_head_grect_c);
s_head_out_template = property_animation_get_animation(head_out_prop);
animation_set_curve(s_head_out_template, AnimationCurveEaseOut);
animation_set_duration(s_head_out_template, s_animation_duration);
//// head in
PropertyAnimation *head_in_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_d, &s_guy_head_grect_b);
s_head_in_template = property_animation_get_animation(head_in_prop);
animation_set_curve(s_head_in_template, AnimationCurveEaseOut);
animation_set_duration(s_head_in_template, s_animation_duration);
}
// free memory on Window close