# Snake - optional carousel screen (base id 9). Smooth-steering 360-degree snake steered by the knob. # Remove it: drop this file from your config's package "files:" list. Nothing else to edit. # Scores (g_sn_top / g_sn_best) + the "Reset scores" settings action live here - fully self-contained. # # GENERATED by scripts/gen_snake.py - edit the generator, not the blocks. Body = a trail of dots # (ring buffer) rendered from a lambda (lv_obj_set_pos), so per-tick cost is constant + shallow. esphome: on_boot: - priority: 655 then: - lambda: 'id(g_present)[9] = true;' - priority: 650 then: - lambda: |- int g = id(g_wgrp_n)++; id(g_wgrp_labels) += (g ? "\n" : ""); id(g_wgrp_labels) += "Snake"; int o = id(g_wopt_n)++; id(g_wopt_group)[o] = g; id(g_wopt_label)[o] = "Reset scores"; id(g_wopt_kind)[o] = 1; id(g_wopt_ptr)[o] = &id(g_sn_reset); globals: - id: g_sn_best type: int restore_value: yes initial_value: '0' - id: g_sn_top type: int[10] restore_value: yes - id: g_sn_reset type: bool restore_value: no initial_value: 'false' - id: g_sn_state # 0=menu 1=playing 2=game over 3=how-to 4=scores type: int restore_value: no initial_value: '0' - id: g_sn_len # body dots in the snake type: int restore_value: no initial_value: '5' - id: g_sn_score type: int restore_value: no initial_value: '0' - id: g_sn_tx # body trail dots X (ring buffer; centre coords px) type: float[100] restore_value: no - id: g_sn_ty type: float[100] restore_value: no - id: g_sn_head # ring index of the newest dot type: int restore_value: no initial_value: '0' - id: g_sn_hx # smooth head position (leads the newest dot) type: float restore_value: no initial_value: '0.0' - id: g_sn_hy type: float restore_value: no initial_value: '0.0' - id: g_sn_ang # heading (radians) type: float restore_value: no initial_value: '0.0' - id: g_sn_grow # pending growth (appends that won't drop the tail) type: int restore_value: no initial_value: '0' - id: g_sn_dead type: bool restore_value: no initial_value: 'false' - id: g_sn_add # ring slot to show/position this tick (-1 none) type: int restore_value: no initial_value: '-1' - id: g_sn_del # ring slot to park off-screen this tick (-1 none) type: int restore_value: no initial_value: '-1' - id: g_sn_fx type: float[3] restore_value: no - id: g_sn_fy type: float[3] restore_value: no - id: g_sn_fi type: int[3] restore_value: no - id: g_sn_fon type: bool[3] restore_value: no - id: g_sn_fclk type: int restore_value: no initial_value: '0' - id: g_sn_newfruit type: int restore_value: no initial_value: '-1' - id: g_sn_skx type: float[2] restore_value: no - id: g_sn_sky type: float[2] restore_value: no - id: g_sn_skon type: bool[2] restore_value: no - id: g_sn_skage type: int[2] restore_value: no - id: g_sn_skclk type: int restore_value: no initial_value: '0' - id: g_sn_newskull type: int restore_value: no initial_value: '-1' script: - id: sn_fspr0 then: - lvgl.widget.update: { id: sn_fruit0, hidden: false, x: !lambda 'return (int) lroundf(id(g_sn_fx)[0]);', y: !lambda 'return (int) lroundf(id(g_sn_fy)[0]);' } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 0;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit0 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 1;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit1 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 2;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit2 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 3;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit3 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 4;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit4 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 5;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit5 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 6;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit6 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 7;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit7 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 8;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit8 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 9;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit9 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 10;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit10 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[0] == 11;' }, then: [ lvgl.image.update: { id: sn_fruit0, src: img_sn_fruit11 } ] } - id: sn_fspr1 then: - lvgl.widget.update: { id: sn_fruit1, hidden: false, x: !lambda 'return (int) lroundf(id(g_sn_fx)[1]);', y: !lambda 'return (int) lroundf(id(g_sn_fy)[1]);' } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 0;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit0 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 1;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit1 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 2;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit2 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 3;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit3 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 4;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit4 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 5;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit5 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 6;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit6 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 7;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit7 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 8;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit8 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 9;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit9 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 10;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit10 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[1] == 11;' }, then: [ lvgl.image.update: { id: sn_fruit1, src: img_sn_fruit11 } ] } - id: sn_fspr2 then: - lvgl.widget.update: { id: sn_fruit2, hidden: false, x: !lambda 'return (int) lroundf(id(g_sn_fx)[2]);', y: !lambda 'return (int) lroundf(id(g_sn_fy)[2]);' } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 0;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit0 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 1;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit1 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 2;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit2 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 3;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit3 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 4;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit4 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 5;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit5 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 6;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit6 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 7;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit7 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 8;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit8 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 9;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit9 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 10;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit10 } ] } - if: { condition: { lambda: 'return id(g_sn_fi)[2] == 11;' }, then: [ lvgl.image.update: { id: sn_fruit2, src: img_sn_fruit11 } ] } - id: sn_hud then: - lvgl.label.update: { id: lbl_sn_score, text: !lambda 'char b[12]; snprintf(b,sizeof(b),"%d",id(g_sn_score)); return std::string(b);' } - id: sn_items then: - lvgl.widget.update: { id: sn_fruit0, hidden: !lambda 'return !id(g_sn_fon)[0];' } - lvgl.widget.update: { id: sn_fruit1, hidden: !lambda 'return !id(g_sn_fon)[1];' } - lvgl.widget.update: { id: sn_fruit2, hidden: !lambda 'return !id(g_sn_fon)[2];' } - lvgl.widget.update: { id: sn_skull0, hidden: !lambda 'return !id(g_sn_skon)[0];' } - lvgl.widget.update: { id: sn_skull1, hidden: !lambda 'return !id(g_sn_skon)[1];' } # full body redraw - used at start / when (re)entering the play screen (one lambda, not per tick) - id: sn_drawfull then: - lambda: |- lv_obj_t *SS[100] = { id(sn_seg0), id(sn_seg1), id(sn_seg2), id(sn_seg3), id(sn_seg4), id(sn_seg5), id(sn_seg6), id(sn_seg7), id(sn_seg8), id(sn_seg9), id(sn_seg10), id(sn_seg11), id(sn_seg12), id(sn_seg13), id(sn_seg14), id(sn_seg15), id(sn_seg16), id(sn_seg17), id(sn_seg18), id(sn_seg19), id(sn_seg20), id(sn_seg21), id(sn_seg22), id(sn_seg23), id(sn_seg24), id(sn_seg25), id(sn_seg26), id(sn_seg27), id(sn_seg28), id(sn_seg29), id(sn_seg30), id(sn_seg31), id(sn_seg32), id(sn_seg33), id(sn_seg34), id(sn_seg35), id(sn_seg36), id(sn_seg37), id(sn_seg38), id(sn_seg39), id(sn_seg40), id(sn_seg41), id(sn_seg42), id(sn_seg43), id(sn_seg44), id(sn_seg45), id(sn_seg46), id(sn_seg47), id(sn_seg48), id(sn_seg49), id(sn_seg50), id(sn_seg51), id(sn_seg52), id(sn_seg53), id(sn_seg54), id(sn_seg55), id(sn_seg56), id(sn_seg57), id(sn_seg58), id(sn_seg59), id(sn_seg60), id(sn_seg61), id(sn_seg62), id(sn_seg63), id(sn_seg64), id(sn_seg65), id(sn_seg66), id(sn_seg67), id(sn_seg68), id(sn_seg69), id(sn_seg70), id(sn_seg71), id(sn_seg72), id(sn_seg73), id(sn_seg74), id(sn_seg75), id(sn_seg76), id(sn_seg77), id(sn_seg78), id(sn_seg79), id(sn_seg80), id(sn_seg81), id(sn_seg82), id(sn_seg83), id(sn_seg84), id(sn_seg85), id(sn_seg86), id(sn_seg87), id(sn_seg88), id(sn_seg89), id(sn_seg90), id(sn_seg91), id(sn_seg92), id(sn_seg93), id(sn_seg94), id(sn_seg95), id(sn_seg96), id(sn_seg97), id(sn_seg98), id(sn_seg99) }; for (int k = 0; k < 100; k++) { int d = (id(g_sn_head) - k + 400) % 100; if (d < id(g_sn_len)) lv_obj_set_pos(SS[k], 180 + (int) lroundf(id(g_sn_tx)[k]) - 4, 180 + (int) lroundf(id(g_sn_ty)[k]) - 4); else lv_obj_set_pos(SS[k], 400, 400); } lv_obj_set_pos(id(sn_head), 180 + (int) lroundf(id(g_sn_hx)) - 4, 180 + (int) lroundf(id(g_sn_hy)) - 4); - script.execute: sn_items # hide every gameplay widget (park body off-screen + hide fruit/skulls) - id: sn_clear then: - lambda: |- lv_obj_t *SS[100] = { id(sn_seg0), id(sn_seg1), id(sn_seg2), id(sn_seg3), id(sn_seg4), id(sn_seg5), id(sn_seg6), id(sn_seg7), id(sn_seg8), id(sn_seg9), id(sn_seg10), id(sn_seg11), id(sn_seg12), id(sn_seg13), id(sn_seg14), id(sn_seg15), id(sn_seg16), id(sn_seg17), id(sn_seg18), id(sn_seg19), id(sn_seg20), id(sn_seg21), id(sn_seg22), id(sn_seg23), id(sn_seg24), id(sn_seg25), id(sn_seg26), id(sn_seg27), id(sn_seg28), id(sn_seg29), id(sn_seg30), id(sn_seg31), id(sn_seg32), id(sn_seg33), id(sn_seg34), id(sn_seg35), id(sn_seg36), id(sn_seg37), id(sn_seg38), id(sn_seg39), id(sn_seg40), id(sn_seg41), id(sn_seg42), id(sn_seg43), id(sn_seg44), id(sn_seg45), id(sn_seg46), id(sn_seg47), id(sn_seg48), id(sn_seg49), id(sn_seg50), id(sn_seg51), id(sn_seg52), id(sn_seg53), id(sn_seg54), id(sn_seg55), id(sn_seg56), id(sn_seg57), id(sn_seg58), id(sn_seg59), id(sn_seg60), id(sn_seg61), id(sn_seg62), id(sn_seg63), id(sn_seg64), id(sn_seg65), id(sn_seg66), id(sn_seg67), id(sn_seg68), id(sn_seg69), id(sn_seg70), id(sn_seg71), id(sn_seg72), id(sn_seg73), id(sn_seg74), id(sn_seg75), id(sn_seg76), id(sn_seg77), id(sn_seg78), id(sn_seg79), id(sn_seg80), id(sn_seg81), id(sn_seg82), id(sn_seg83), id(sn_seg84), id(sn_seg85), id(sn_seg86), id(sn_seg87), id(sn_seg88), id(sn_seg89), id(sn_seg90), id(sn_seg91), id(sn_seg92), id(sn_seg93), id(sn_seg94), id(sn_seg95), id(sn_seg96), id(sn_seg97), id(sn_seg98), id(sn_seg99) }; for (int k = 0; k < 100; k++) lv_obj_set_pos(SS[k], 400, 400); lv_obj_set_pos(id(sn_head), 400, 400); - lvgl.widget.hide: sn_fruit0 - lvgl.widget.hide: sn_fruit1 - lvgl.widget.hide: sn_fruit2 - lvgl.widget.hide: sn_skull0 - lvgl.widget.hide: sn_skull1 - id: sn_start then: - lambda: |- id(g_sn_state) = 1; id(g_sn_score) = 0; id(g_sn_dead) = false; id(g_sn_ang) = -1.5708f; id(g_sn_grow) = 0; // heading up id(g_sn_len) = 5; id(g_sn_head) = 4; for (int i = 0; i < 100; i++) { id(g_sn_tx)[i] = 0.0f; id(g_sn_ty)[i] = 0.0f; } for (int k = 0; k < 5; k++) { id(g_sn_tx)[k] = 0.0f; id(g_sn_ty)[k] = (4 - k) * 8.0f; } id(g_sn_hx) = 0.0f; id(g_sn_hy) = 0.0f; for (int s = 0; s < 3; s++) id(g_sn_fon)[s] = false; for (int s = 0; s < 2; s++) { id(g_sn_skon)[s] = false; id(g_sn_skage)[s] = 0; } id(g_sn_fclk) = 0; id(g_sn_skclk) = 0; id(g_sn_newfruit) = -1; id(g_sn_newskull) = -1; id(g_sn_add) = -1; id(g_sn_del) = -1; id(g_knob_capture) = true; id(g_knob_delta) = 0; float a = (esp_random() % 62832) / 10000.0f; float rad = 60.0f + (esp_random() % 80); id(g_sn_fx)[0] = cosf(a)*rad; id(g_sn_fy)[0] = sinf(a)*rad; id(g_sn_fi)[0] = esp_random() % 12; id(g_sn_fon)[0] = true; - script.execute: sn_fspr0 - script.execute: sn_screen - script.execute: sn_drawfull - script.execute: sn_hud - id: sn_over then: - lambda: |- id(g_sn_state) = 2; int s = id(g_sn_score); if (s > id(g_sn_best)) id(g_sn_best) = s; for (int i = 0; i < 10; i++) { if (s > id(g_sn_top)[i]) { for (int j = 9; j > i; j--) id(g_sn_top)[j] = id(g_sn_top)[j-1]; id(g_sn_top)[i] = s; break; } } - script.execute: sn_screen # screen state + the single knob-capture authority (captured only in play + game over) - id: sn_screen then: - lambda: 'id(g_knob_capture) = (id(g_sn_state) == 1 || id(g_sn_state) == 2);' - lvgl.widget.hide: sn_ring - script.execute: sn_clear - lvgl.widget.hide: lbl_sn_score - lvgl.widget.hide: sn_logo - lvgl.widget.hide: btn_sn_start - lvgl.widget.hide: btn_sn_howto - lvgl.widget.hide: btn_sn_scores - lvgl.widget.hide: lbl_sn_over - lvgl.widget.hide: lbl_sn_rec - lvgl.widget.hide: btn_sn_replay - lvgl.widget.hide: btn_sn_exit - lvgl.widget.hide: lbl_sn_howto_t - lvgl.widget.hide: sn_b1 - lvgl.widget.hide: sn_b2 - lvgl.widget.hide: sn_b3 - lvgl.widget.hide: sn_b4 - lvgl.widget.hide: lbl_sn_howto1 - lvgl.widget.hide: lbl_sn_howto2 - lvgl.widget.hide: lbl_sn_howto3 - lvgl.widget.hide: lbl_sn_howto4 - lvgl.widget.hide: lbl_sn_scores_t - lvgl.widget.hide: lbl_sn_scores1 - lvgl.widget.hide: lbl_sn_scores2 - lvgl.widget.hide: btn_sn_back - if: # MENU condition: { lambda: 'return id(g_sn_state) == 0;' } then: - lvgl.widget.show: sn_logo - lvgl.widget.show: btn_sn_start - lvgl.widget.show: btn_sn_howto - lvgl.widget.show: btn_sn_scores - if: # PLAY condition: { lambda: 'return id(g_sn_state) == 1;' } then: - lvgl.widget.show: sn_ring - lvgl.widget.show: lbl_sn_score - script.execute: sn_drawfull - if: # GAME OVER condition: { lambda: 'return id(g_sn_state) == 2;' } then: - lvgl.widget.show: sn_logo - lvgl.widget.show: lbl_sn_over - lvgl.widget.show: lbl_sn_rec - lvgl.widget.show: btn_sn_replay - lvgl.widget.show: btn_sn_exit - lvgl.label.update: { id: lbl_sn_over, text: !lambda 'char b[24]; snprintf(b,sizeof(b),"Score: %d", id(g_sn_score)); return std::string(b);' } - lvgl.label.update: { id: lbl_sn_rec, text: !lambda 'char b[24]; snprintf(b,sizeof(b),"Best: %d", id(g_sn_best)); return std::string(b);' } - if: # HOW TO PLAY condition: { lambda: 'return id(g_sn_state) == 3;' } then: - lvgl.widget.show: lbl_sn_howto_t - lvgl.widget.show: sn_b1 - lvgl.widget.show: sn_b2 - lvgl.widget.show: sn_b3 - lvgl.widget.show: sn_b4 - lvgl.widget.show: lbl_sn_howto1 - lvgl.widget.show: lbl_sn_howto2 - lvgl.widget.show: lbl_sn_howto3 - lvgl.widget.show: lbl_sn_howto4 - lvgl.widget.show: btn_sn_back - if: # SCORES (top 10) condition: { lambda: 'return id(g_sn_state) == 4;' } then: - lvgl.widget.show: lbl_sn_scores_t - lvgl.widget.show: lbl_sn_scores1 - lvgl.widget.show: lbl_sn_scores2 - lvgl.widget.show: btn_sn_back - lvgl.label.update: id: lbl_sn_scores1 text: !lambda |- std::string s; char b[24]; for (int i = 0; i < 5; i++) { if(i) s += "\n"; if(id(g_sn_top)[i]>0){ snprintf(b,sizeof(b),"%d. %d",i+1,id(g_sn_top)[i]); } else { snprintf(b,sizeof(b),"%d. -",i+1); } s += b; } return s; - lvgl.label.update: id: lbl_sn_scores2 text: !lambda |- std::string s; char b[24]; for (int i = 5; i < 10; i++) { if(i>5) s += "\n"; if(id(g_sn_top)[i]>0){ snprintf(b,sizeof(b),"%d. %d",i+1,id(g_sn_top)[i]); } else { snprintf(b,sizeof(b),"%d. -",i+1); } s += b; } return s; interval: - interval: 250ms then: - if: condition: { lambda: 'return id(g_sn_reset) || id(g_factory_reset);' } then: - lambda: 'for (int i = 0; i < 10; i++) id(g_sn_top)[i] = 0; id(g_sn_best) = 0; id(g_sn_reset) = false;' - interval: 50ms then: - if: condition: { lambda: 'return id(g_nav_req) && id(g_base)==9;' } then: - lambda: 'id(g_nav_req) = false; id(g_sn_state) = 0; id(g_knob_delta) = 0;' - if: { condition: { lambda: 'return id(g_nav_anim)==0;' }, then: [lvgl.page.show: { id: page_snake, animation: move_left, time: 250ms }] } - if: { condition: { lambda: 'return id(g_nav_anim)==1;' }, then: [lvgl.page.show: { id: page_snake, animation: move_right, time: 250ms }] } - if: { condition: { lambda: 'return id(g_nav_anim)==2;' }, then: [lvgl.page.show: { id: page_snake, animation: move_top, time: 250ms }] } - if: { condition: { lambda: 'return id(g_nav_anim)==3;' }, then: [lvgl.page.show: { id: page_snake, animation: move_bottom, time: 250ms }] } - script.execute: sn_screen # Game tick: steer + glide head; lay/drop one trail dot when the head advanced SEG_DIST. # All body/head positioning is done IN this lambda (lv_obj_set_pos) to keep the action chain shallow. - interval: 50ms then: - if: condition: { lambda: 'return id(g_base) == 9 && id(g_sn_state) == 1;' } then: - lambda: |- id(g_sn_add) = -1; id(g_sn_del) = -1; id(g_sn_newfruit) = -1; id(g_sn_newskull) = -1; int kd = id(g_knob_delta); id(g_knob_delta) = 0; id(g_sn_ang) += kd * 0.26f; float spd = 3.2f + id(g_sn_score) / 400.0f; if (spd > 5.5f) spd = 5.5f; float hx = id(g_sn_hx) + cosf(id(g_sn_ang)) * spd; float hy = id(g_sn_hy) + sinf(id(g_sn_ang)) * spd; if (hx*hx + hy*hy > 168.0f * 168.0f) { id(g_sn_dead) = true; } // hit the ring else { id(g_sn_hx) = hx; id(g_sn_hy) = hy; int len = id(g_sn_len), head = id(g_sn_head); for (int i = 6; i < len; i++) { int sl = (head - i + 400) % 100; float dx = hx - id(g_sn_tx)[sl], dy = hy - id(g_sn_ty)[sl]; if (dx*dx + dy*dy < 8.0f * 8.0f) { id(g_sn_dead) = true; break; } } for (int s = 0; s < 2; s++) if (id(g_sn_skon)[s]) { float dx = hx - id(g_sn_skx)[s], dy = hy - id(g_sn_sky)[s]; if (dx*dx + dy*dy < 13.0f * 13.0f) { id(g_sn_dead) = true; } } for (int s = 0; s < 3 && !id(g_sn_dead); s++) if (id(g_sn_fon)[s]) { float dx = hx - id(g_sn_fx)[s], dy = hy - id(g_sn_fy)[s]; if (dx*dx + dy*dy < 12.0f * 12.0f) { id(g_sn_fon)[s] = false; id(g_sn_score) += 10; id(g_sn_grow) += 3; } } if (!id(g_sn_dead)) { float dx = hx - id(g_sn_tx)[head], dy = hy - id(g_sn_ty)[head]; if (dx*dx + dy*dy >= 8.0f * 8.0f) { int nh = (head + 1) % 100; id(g_sn_tx)[nh] = hx; id(g_sn_ty)[nh] = hy; id(g_sn_head) = nh; id(g_sn_add) = nh; if (id(g_sn_grow) > 0 && id(g_sn_len) < 99) { id(g_sn_grow)--; id(g_sn_len)++; id(g_sn_del) = -1; } // cap at POOL-1: the ring needs one free slot or add/drop collide else { if (id(g_sn_grow) > 0) id(g_sn_grow)--; id(g_sn_del) = (head - id(g_sn_len) + 1 + 400) % 100; } } } } if (!id(g_sn_dead)) { int fc = 0; for (int s = 0; s < 3; s++) if (id(g_sn_fon)[s]) fc++; id(g_sn_fclk)++; int wait = (fc <= 1) ? 45 : 90; if (fc < 3 && id(g_sn_fclk) >= wait) { id(g_sn_fclk) = 0; int sl = -1; for (int s = 0; s < 3; s++) if (!id(g_sn_fon)[s]) { sl = s; break; } if (sl >= 0) { float a = (esp_random() % 62832) / 10000.0f; float rad = 25.0f + (esp_random() % 140); id(g_sn_fx)[sl] = cosf(a)*rad; id(g_sn_fy)[sl] = sinf(a)*rad; id(g_sn_fi)[sl] = esp_random() % 12; id(g_sn_fon)[sl] = true; id(g_sn_newfruit) = sl; } } int sc = 0; for (int s = 0; s < 2; s++) if (id(g_sn_skon)[s]) sc++; id(g_sn_skclk)++; if (sc < 2 && id(g_sn_skclk) >= 200) { id(g_sn_skclk) = 0; int sl = -1; for (int s = 0; s < 2; s++) if (!id(g_sn_skon)[s]) { sl = s; break; } if (sl >= 0) { float a = (esp_random() % 62832) / 10000.0f; float rad = 30.0f + (esp_random() % 130); id(g_sn_skx)[sl] = cosf(a)*rad; id(g_sn_sky)[sl] = sinf(a)*rad; id(g_sn_skon)[sl] = true; id(g_sn_skage)[sl] = 0; id(g_sn_newskull) = sl; } } for (int s = 0; s < 2; s++) if (id(g_sn_skon)[s]) { id(g_sn_skage)[s]++; if (id(g_sn_skage)[s] >= 220) id(g_sn_skon)[s] = false; } // render (constant cost): head every tick + the one added/dropped dot lv_obj_set_pos(id(sn_head), 180 + (int) lroundf(id(g_sn_hx)) - 4, 180 + (int) lroundf(id(g_sn_hy)) - 4); if (id(g_sn_add) >= 0 || id(g_sn_del) >= 0) { lv_obj_t *SS[100] = { id(sn_seg0), id(sn_seg1), id(sn_seg2), id(sn_seg3), id(sn_seg4), id(sn_seg5), id(sn_seg6), id(sn_seg7), id(sn_seg8), id(sn_seg9), id(sn_seg10), id(sn_seg11), id(sn_seg12), id(sn_seg13), id(sn_seg14), id(sn_seg15), id(sn_seg16), id(sn_seg17), id(sn_seg18), id(sn_seg19), id(sn_seg20), id(sn_seg21), id(sn_seg22), id(sn_seg23), id(sn_seg24), id(sn_seg25), id(sn_seg26), id(sn_seg27), id(sn_seg28), id(sn_seg29), id(sn_seg30), id(sn_seg31), id(sn_seg32), id(sn_seg33), id(sn_seg34), id(sn_seg35), id(sn_seg36), id(sn_seg37), id(sn_seg38), id(sn_seg39), id(sn_seg40), id(sn_seg41), id(sn_seg42), id(sn_seg43), id(sn_seg44), id(sn_seg45), id(sn_seg46), id(sn_seg47), id(sn_seg48), id(sn_seg49), id(sn_seg50), id(sn_seg51), id(sn_seg52), id(sn_seg53), id(sn_seg54), id(sn_seg55), id(sn_seg56), id(sn_seg57), id(sn_seg58), id(sn_seg59), id(sn_seg60), id(sn_seg61), id(sn_seg62), id(sn_seg63), id(sn_seg64), id(sn_seg65), id(sn_seg66), id(sn_seg67), id(sn_seg68), id(sn_seg69), id(sn_seg70), id(sn_seg71), id(sn_seg72), id(sn_seg73), id(sn_seg74), id(sn_seg75), id(sn_seg76), id(sn_seg77), id(sn_seg78), id(sn_seg79), id(sn_seg80), id(sn_seg81), id(sn_seg82), id(sn_seg83), id(sn_seg84), id(sn_seg85), id(sn_seg86), id(sn_seg87), id(sn_seg88), id(sn_seg89), id(sn_seg90), id(sn_seg91), id(sn_seg92), id(sn_seg93), id(sn_seg94), id(sn_seg95), id(sn_seg96), id(sn_seg97), id(sn_seg98), id(sn_seg99) }; if (id(g_sn_add) >= 0) lv_obj_set_pos(SS[id(g_sn_add)], 180 + (int) lroundf(id(g_sn_tx)[id(g_sn_add)]) - 4, 180 + (int) lroundf(id(g_sn_ty)[id(g_sn_add)]) - 4); if (id(g_sn_del) >= 0) lv_obj_set_pos(SS[id(g_sn_del)], 400, 400); } } - if: condition: { lambda: 'return id(g_sn_dead);' } then: - script.execute: sn_over else: - if: condition: { lambda: 'return id(g_sn_newfruit) >= 0;' } then: - if: { condition: { lambda: 'return id(g_sn_newfruit) == 0;' }, then: [ script.execute: sn_fspr0 ] } - if: { condition: { lambda: 'return id(g_sn_newfruit) == 1;' }, then: [ script.execute: sn_fspr1 ] } - if: { condition: { lambda: 'return id(g_sn_newfruit) == 2;' }, then: [ script.execute: sn_fspr2 ] } - if: condition: { lambda: 'return id(g_sn_newskull) >= 0;' } then: - if: { condition: { lambda: 'return id(g_sn_newskull) == 0;' }, then: [ lvgl.widget.update: { id: sn_skull0, hidden: false, x: !lambda 'return (int) lroundf(id(g_sn_skx)[0]);', y: !lambda 'return (int) lroundf(id(g_sn_sky)[0]);' } ] } - if: { condition: { lambda: 'return id(g_sn_newskull) == 1;' }, then: [ lvgl.widget.update: { id: sn_skull1, hidden: false, x: !lambda 'return (int) lroundf(id(g_sn_skx)[1]);', y: !lambda 'return (int) lroundf(id(g_sn_sky)[1]);' } ] } - script.execute: sn_items - script.execute: sn_hud image: - id: img_sn_logo file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/snake-logo.png" type: RGB565 - id: img_sn_fruit0 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit0.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit1 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit1.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit2 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit2.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit3 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit3.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit4 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit4.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit5 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit5.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit6 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit6.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit7 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit7.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit8 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit8.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit9 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit9.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit10 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit10.png" type: RGB565 transparency: alpha_channel - id: img_sn_fruit11 file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/fruit11.png" type: RGB565 transparency: alpha_channel - id: img_sn_skull file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/snake/skull.png" type: RGB565 transparency: alpha_channel lvgl: pages: - id: page_snake bg_color: 0x0D1E15 scrollbar_mode: "off" scrollable: false widgets: - obj: { id: sn_ring, align: CENTER, x: 0, y: 0, width: 344, height: 344, radius: 172, bg_opa: TRANSP, border_width: 4, border_color: 0x3A8C4E, hidden: true } - image: { id: sn_fruit0, align: CENTER, x: 0, y: 0, src: img_sn_fruit0, hidden: true } - image: { id: sn_fruit1, align: CENTER, x: 0, y: 0, src: img_sn_fruit0, hidden: true } - image: { id: sn_fruit2, align: CENTER, x: 0, y: 0, src: img_sn_fruit0, hidden: true } - image: { id: sn_skull0, align: CENTER, x: 0, y: 0, src: img_sn_skull, hidden: true } - image: { id: sn_skull1, align: CENTER, x: 0, y: 0, src: img_sn_skull, hidden: true } - obj: { id: sn_seg0, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg1, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg2, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg3, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg4, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg5, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg6, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg7, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg8, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg9, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg10, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg11, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg12, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg13, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg14, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg15, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg16, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg17, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg18, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg19, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg20, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg21, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg22, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg23, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg24, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg25, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg26, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg27, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg28, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg29, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg30, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg31, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg32, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg33, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg34, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg35, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg36, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg37, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg38, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg39, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg40, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg41, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg42, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg43, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg44, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg45, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg46, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg47, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg48, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg49, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg50, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg51, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg52, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg53, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg54, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg55, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg56, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg57, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg58, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg59, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg60, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg61, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg62, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg63, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg64, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg65, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg66, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg67, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg68, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg69, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg70, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg71, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg72, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg73, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg74, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg75, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg76, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg77, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg78, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg79, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg80, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg81, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg82, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg83, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg84, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg85, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg86, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg87, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg88, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg89, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg90, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg91, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg92, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg93, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg94, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg95, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg96, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg97, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg98, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_seg99, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0x52A049, bg_opa: COVER } - obj: { id: sn_head, x: 400, y: 400, width: 9, height: 9, radius: 4, border_width: 0, bg_color: 0xB8E86A, bg_opa: COVER } - label: { id: lbl_sn_score, align: CENTER, x: 0, y: -150, text: "0", text_font: font_med, text_color: 0xCFEAE4, hidden: true } - image: { id: sn_logo, align: CENTER, x: 0, y: 0, src: img_sn_logo, hidden: true } - button: id: btn_sn_start align: CENTER y: 4 width: 150 height: 44 radius: 22 bg_color: 0xA6D85F bg_opa: COVER border_width: 0 on_click: [ script.execute: sn_start ] widgets: - label: { align: CENTER, text: "Start", text_font: font_med, text_color: 0x12241A } - button: id: btn_sn_howto align: CENTER y: 54 width: 150 height: 44 radius: 22 bg_color: 0x244A30 bg_opa: COVER border_width: 0 on_click: [ lambda: 'id(g_sn_state) = 3;', script.execute: sn_screen ] widgets: - label: { align: CENTER, text: "How to play?", text_font: font_med, text_color: 0xCFE6C4 } - button: id: btn_sn_scores align: CENTER y: 104 width: 150 height: 44 radius: 22 bg_color: 0x244A30 bg_opa: COVER border_width: 0 on_click: [ lambda: 'id(g_sn_state) = 4;', script.execute: sn_screen ] widgets: - label: { align: CENTER, text: "Scores", text_font: font_med, text_color: 0xCFE6C4 } - label: { id: lbl_sn_over, align: CENTER, x: 0, y: -10, text_align: CENTER, text: "", text_font: font_sel, text_color: 0x12212D, hidden: true } - label: { id: lbl_sn_rec, align: CENTER, x: 0, y: 22, text_align: CENTER, text: "", text_font: font_artist, text_color: 0x12212D, hidden: true } - button: id: btn_sn_replay align: CENTER x: -66 y: 62 width: 112 height: 48 radius: 24 bg_color: 0xA6D85F bg_opa: COVER border_width: 0 hidden: true on_click: [ script.execute: sn_start ] widgets: - label: { align: CENTER, text: "Play", text_font: font_med, text_color: 0x12241A } - button: id: btn_sn_exit align: CENTER x: 66 y: 62 width: 112 height: 48 radius: 24 bg_color: 0x3A3A3D bg_opa: COVER border_width: 0 hidden: true on_click: [ lambda: 'id(g_sn_state) = 0;', script.execute: sn_screen ] widgets: - label: { align: CENTER, text: "Exit", text_font: font_med, text_color: 0xFFFFFF } - label: { id: lbl_sn_howto_t, align: CENTER, y: -104, text: "HOW TO PLAY?", text_font: font_sel, text_color: 0xA6D85F, hidden: true } - obj: { id: sn_b1, align: CENTER, x: -96, y: -52, width: 24, height: 24, radius: 12, bg_color: 0x6FB23F, bg_opa: COVER, border_width: 0, pad_all: 0, hidden: true, widgets: [ label: { align: CENTER, text: "1", text_font: font_artist, text_color: 0xFFFFFF } ] } - obj: { id: sn_b2, align: CENTER, x: -96, y: -16, width: 24, height: 24, radius: 12, bg_color: 0x6FB23F, bg_opa: COVER, border_width: 0, pad_all: 0, hidden: true, widgets: [ label: { align: CENTER, text: "2", text_font: font_artist, text_color: 0xFFFFFF } ] } - obj: { id: sn_b3, align: CENTER, x: -96, y: 20, width: 24, height: 24, radius: 12, bg_color: 0x6FB23F, bg_opa: COVER, border_width: 0, pad_all: 0, hidden: true, widgets: [ label: { align: CENTER, text: "3", text_font: font_artist, text_color: 0xFFFFFF } ] } - obj: { id: sn_b4, align: CENTER, x: -96, y: 56, width: 24, height: 24, radius: 12, bg_color: 0xE05A4A, bg_opa: COVER, border_width: 0, pad_all: 0, hidden: true, widgets: [ label: { align: CENTER, text: "!", text_font: font_artist, text_color: 0xFFFFFF } ] } - label: { id: lbl_sn_howto1, align_to: { id: sn_b1, align: OUT_RIGHT_MID, x: 8 }, text: "Turn knob to steer", text_font: font_med, text_color: 0xC6DCC0, hidden: true } - label: { id: lbl_sn_howto2, align_to: { id: sn_b2, align: OUT_RIGHT_MID, x: 8 }, text: "Eat fruit to grow", text_font: font_med, text_color: 0xC6DCC0, hidden: true } - label: { id: lbl_sn_howto3, align_to: { id: sn_b3, align: OUT_RIGHT_MID, x: 8 }, text: "Avoid the ring & tail", text_font: font_med, text_color: 0xC6DCC0, hidden: true } - label: { id: lbl_sn_howto4, align_to: { id: sn_b4, align: OUT_RIGHT_MID, x: 8 }, text: "Skulls kill - avoid!", text_font: font_med, text_color: 0xC6DCC0, hidden: true } - label: { id: lbl_sn_scores_t, align: CENTER, y: -116, text: "SCORES", text_font: font_sel, text_color: 0xA6D85F, hidden: true } - label: { id: lbl_sn_scores1, align: CENTER, x: -52, y: 0, text: "", text_align: LEFT, text_font: font_artist, text_color: 0xC6DCC0, hidden: true } - label: { id: lbl_sn_scores2, align: CENTER, x: 56, y: 0, text: "", text_align: LEFT, text_font: font_artist, text_color: 0xC6DCC0, hidden: true } - button: id: btn_sn_back align: CENTER y: 120 width: 130 height: 42 radius: 21 bg_color: 0x3A3A3D bg_opa: COVER border_width: 0 hidden: true on_click: [ lambda: 'id(g_sn_state) = 0;', script.execute: sn_screen ] widgets: - label: { align: CENTER, text: "Back", text_font: font_med, text_color: 0xFFFFFF }