Files
2026-07-19 16:49:55 +08:00

499 lines
25 KiB
YAML

# Space Wars - optional carousel screen (base id 4). Vertical shooter.
# Remove it: drop this file from your config's package "files:" list. Nothing else to edit.
# Scores (g_sw_top / g_sw_best) + the "Reset scores" settings action live here - fully self-contained.
esphome:
on_boot:
- priority: 660
then:
- lambda: 'id(g_present)[4] = true;' # register after clock/player/timer/cars
# Settings (Settings -> Widgets -> Space Wars -> Reset scores) + factory-reset handling.
- priority: 650
then:
- lambda: |-
int g = id(g_wgrp_n)++;
id(g_wgrp_labels) += (g ? "\n" : ""); id(g_wgrp_labels) += "Space Wars";
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_sw_reset);
globals:
# --- scores (persistent) + reset flag, owned by this package ---
- id: g_sw_best
type: int
restore_value: yes
initial_value: '0'
- id: g_sw_top
type: int[10]
restore_value: yes
- id: g_sw_reset # Widgets "Reset scores" sets this; the watcher below clears the scores
type: bool
restore_value: no
initial_value: 'false'
# --- Game 2 "Space Wars" (page_game2, g_base==4) ---
- id: g_sw_state # 0=menu 1=playing 2=game over 3=how-to 4=scores
type: int
restore_value: no
initial_value: '0'
- id: g_sw_px # player ship X
type: int
restore_value: no
initial_value: '0'
- id: g_sw_lives
type: int
restore_value: no
initial_value: '3'
- id: g_sw_inv
type: int
restore_value: no
initial_value: '0'
- id: g_sw_score
type: int
restore_value: no
initial_value: '0'
- id: g_fire # auto-fire cadence counter
type: int
restore_value: no
initial_value: '0'
- id: g_tcount # time counter (points for time survived)
type: int
restore_value: no
initial_value: '0'
- id: g_sw_crash
type: bool
restore_value: no
initial_value: 'false'
- id: g_b_x # player bullets (2): X
type: int[2]
restore_value: no
- id: g_b_y
type: int[2]
restore_value: no
- id: g_b_on
type: bool[2]
restore_value: no
- id: g_en_x # enemies (3)
type: int[3]
restore_value: no
- id: g_en_y
type: int[3]
restore_value: no
- id: g_en_on
type: bool[3]
restore_value: no
- id: g_eb_x # enemy bullets (2)
type: int[2]
restore_value: no
- id: g_eb_y
type: int[2]
restore_value: no
- id: g_eb_on
type: bool[2]
restore_value: no
- id: g_exp_f # explosion: countdown frame counter (0=inactive), ticks in the 70ms loop
type: int
restore_value: no
initial_value: '0'
- id: g_exp_x # explosion: position (from the destroyed enemy)
type: int
restore_value: no
initial_value: '0'
- id: g_exp_y
type: int
restore_value: no
initial_value: '0'
- id: g_exp_new # flag: start the animation this tick
type: bool
restore_value: no
initial_value: 'false'
- id: g_exp_hide # flag: hide the explosion this tick
type: bool
restore_value: no
initial_value: 'false'
script:
# ===== SPACE WARS (game 2) =====
- id: sw_render # ship X + score + lives
then:
- lvgl.widget.update: { id: sw_ship, x: !lambda 'return id(g_sw_px);' }
- lvgl.label.update: { id: lbl_sw_score, text: !lambda 'char b[12]; snprintf(b,sizeof(b),"%d",id(g_sw_score)); return std::string(b);' }
- lvgl.label.update:
id: lbl_sw_lives
text: !lambda |-
std::string h; for (int i=0;i<id(g_sw_lives);i++) h += "󰋑"; return h;
- id: sw_start
then:
- lambda: |-
id(g_sw_state)=1; id(g_sw_score)=0; id(g_sw_lives)=3; id(g_sw_inv)=0;
id(g_sw_px)=0; id(g_fire)=0; id(g_tcount)=0;
id(g_knob_capture)=true; id(g_knob_delta)=0;
id(g_exp_f)=0; id(g_exp_new)=false; id(g_exp_hide)=false;
for (int i=0;i<2;i++){ id(g_b_on)[i]=false; id(g_eb_on)[i]=false; }
for (int i=0;i<3;i++){ id(g_en_on)[i]=true; id(g_en_x)[i]=(int)(esp_random()%280)-140; id(g_en_y)[i]=-160 - i*70; }
- script.execute: sw_screen
- script.execute: sw_render
- id: sw_lose
then:
- lambda: 'id(g_sw_lives)--; id(g_sw_inv)=16;'
- lvgl.widget.show: sw_flash
- if:
condition: { lambda: 'return id(g_sw_lives) <= 0;' }
then: [ script.execute: sw_over ]
else: [ script.execute: sw_render ]
- id: sw_over
then:
- lambda: |-
id(g_sw_state)=2; // sw_screen keeps the knob captured on game over (no volume)
int s=id(g_sw_score);
if (s>id(g_sw_best)) id(g_sw_best)=s;
for (int i=0;i<10;i++){ if(s>id(g_sw_top)[i]){ for(int j=9;j>i;j--) id(g_sw_top)[j]=id(g_sw_top)[j-1]; id(g_sw_top)[i]=s; break; } }
// reset game state so the end of the current tick restores nothing (red flash / enemies)
id(g_sw_inv)=0;
for(int i=0;i<3;i++) id(g_en_on)[i]=false;
for(int i=0;i<2;i++){ id(g_b_on)[i]=false; id(g_eb_on)[i]=false; }
id(g_exp_f)=0; id(g_exp_new)=false; id(g_exp_hide)=false;
- script.execute: sw_screen
- id: sw_screen # 0=menu 1=playing 2=game over 3=how-to 4=scores
then:
# knob steers only during play + game over -> capture it there (block volume), free it in menu/how-to/scores
- lambda: 'id(g_knob_capture) = (id(g_sw_state) == 1 || id(g_sw_state) == 2);'
- lvgl.widget.hide: sw_bg
- lvgl.widget.hide: sw_logo
- lvgl.widget.hide: sw_ship
- lvgl.widget.hide: sw_exp
- lvgl.widget.hide: b0
- lvgl.widget.hide: b1
- lvgl.widget.hide: eb0
- lvgl.widget.hide: eb1
- lvgl.widget.hide: en0
- lvgl.widget.hide: en1
- lvgl.widget.hide: en2
- lvgl.widget.hide: lbl_sw_lives
- lvgl.widget.hide: lbl_sw_score
- lvgl.widget.hide: sw_flash
- lvgl.widget.hide: btn_sw_start
- lvgl.widget.hide: btn_sw_howto
- lvgl.widget.hide: btn_sw_scores
- lvgl.widget.hide: lbl_sw_over
- lvgl.widget.hide: lbl_sw_rec
- lvgl.widget.hide: btn_sw_replay
- lvgl.widget.hide: btn_sw_exit
- lvgl.widget.hide: lbl_sw_ht_t
- lvgl.widget.hide: badge_h1
- lvgl.widget.hide: badge_h2
- lvgl.widget.hide: badge_h3
- lvgl.widget.hide: badge_h4
- lvgl.widget.hide: lbl_sw_ht1
- lvgl.widget.hide: lbl_sw_ht2
- lvgl.widget.hide: lbl_sw_ht3
- lvgl.widget.hide: lbl_sw_ht4
- lvgl.widget.hide: lbl_sw_hheart
- lvgl.widget.hide: lbl_sw_st
- lvgl.widget.hide: lbl_sw_s1
- lvgl.widget.hide: lbl_sw_s2
- lvgl.widget.hide: btn_sw_back
- if: # MENU
condition: { lambda: 'return id(g_sw_state)==0;' }
then: [ lvgl.widget.show: sw_logo, lvgl.widget.show: btn_sw_start, lvgl.widget.show: btn_sw_howto, lvgl.widget.show: btn_sw_scores ]
- if: # GAME
condition: { lambda: 'return id(g_sw_state)==1;' }
then:
- lvgl.widget.show: sw_bg
- lvgl.widget.show: sw_ship
- lvgl.widget.show: en0
- lvgl.widget.show: en1
- lvgl.widget.show: en2
- lvgl.widget.show: lbl_sw_lives
- lvgl.widget.show: lbl_sw_score
- if: # GAME OVER
condition: { lambda: 'return id(g_sw_state)==2;' }
then:
- lvgl.widget.show: sw_logo
- lvgl.widget.show: lbl_sw_over
- lvgl.widget.show: lbl_sw_rec
- lvgl.widget.show: btn_sw_replay
- lvgl.widget.show: btn_sw_exit
- lvgl.label.update: { id: lbl_sw_over, text: !lambda 'char b[24]; snprintf(b,sizeof(b),"Score: %d", id(g_sw_score)); return std::string(b);' }
- lvgl.label.update: { id: lbl_sw_rec, text: !lambda 'char b[24]; snprintf(b,sizeof(b),"Best: %d", id(g_sw_best)); return std::string(b);' }
- if: # HOW TO PLAY
condition: { lambda: 'return id(g_sw_state)==3;' }
then:
- lvgl.widget.show: sw_bg
- lvgl.widget.show: lbl_sw_ht_t
- lvgl.widget.show: badge_h1
- lvgl.widget.show: badge_h2
- lvgl.widget.show: badge_h3
- lvgl.widget.show: badge_h4
- lvgl.widget.show: lbl_sw_ht1
- lvgl.widget.show: lbl_sw_ht2
- lvgl.widget.show: lbl_sw_ht3
- lvgl.widget.show: lbl_sw_ht4
- lvgl.widget.show: lbl_sw_hheart
- lvgl.widget.show: btn_sw_back
- if: # SCORES
condition: { lambda: 'return id(g_sw_state)==4;' }
then:
- lvgl.widget.show: sw_bg
- lvgl.widget.show: lbl_sw_st
- lvgl.widget.show: lbl_sw_s1
- lvgl.widget.show: lbl_sw_s2
- lvgl.widget.show: btn_sw_back
- lvgl.label.update: { id: lbl_sw_s1, text: !lambda 'std::string s; char b[24]; for(int i=0;i<5;i++){ if(i) s+="\n"; if(id(g_sw_top)[i]>0){ snprintf(b,sizeof(b),"%d. %d",i+1,id(g_sw_top)[i]); } else { snprintf(b,sizeof(b),"%d. -",i+1); } s+=b; } return s;' }
- lvgl.label.update: { id: lbl_sw_s2, text: !lambda 'std::string s; char b[24]; for(int i=5;i<10;i++){ if(i>5) s+="\n"; if(id(g_sw_top)[i]>0){ snprintf(b,sizeof(b),"%d. %d",i+1,id(g_sw_top)[i]); } else { snprintf(b,sizeof(b),"%d. -",i+1); } s+=b; } return s;' }
interval:
# Reset scores when the Widgets action fired (g_sw_reset). Idempotent + cheap.
- interval: 250ms
then:
- if:
condition: { lambda: 'return id(g_sw_reset) || id(g_factory_reset);' }
then:
- lambda: 'for (int i = 0; i < 10; i++) id(g_sw_top)[i] = 0; id(g_sw_best) = 0; id(g_sw_reset) = false;'
# nav: show this screen when it is selected in the carousel
- interval: 50ms
then:
- if:
condition: { lambda: 'return id(g_nav_req) && id(g_base)==4;' }
then:
- lambda: 'id(g_nav_req) = false; id(g_sw_state) = 0;'
- if: { condition: { lambda: 'return id(g_nav_anim)==0;' }, then: [lvgl.page.show: { id: page_game2, animation: move_left, time: 250ms }] }
- if: { condition: { lambda: 'return id(g_nav_anim)==1;' }, then: [lvgl.page.show: { id: page_game2, animation: move_right, time: 250ms }] }
- if: { condition: { lambda: 'return id(g_nav_anim)==2;' }, then: [lvgl.page.show: { id: page_game2, animation: move_top, time: 250ms }] }
- if: { condition: { lambda: 'return id(g_nav_anim)==3;' }, then: [lvgl.page.show: { id: page_game2, animation: move_bottom, time: 250ms }] }
- script.execute: sw_screen
# Space Wars - tick only on the Space screen during play
- interval: 70ms
then:
- if:
condition: { lambda: 'return id(g_base) == 4 && id(g_sw_state) == 1;' }
then:
- lambda: |-
id(g_sw_px) += id(g_knob_delta) * 18; if (id(g_sw_px) < -150) id(g_sw_px) = -150; if (id(g_sw_px) > 150) id(g_sw_px) = 150; id(g_knob_delta) = 0;
int px = id(g_sw_px);
if (id(g_sw_inv) > 0) id(g_sw_inv)--;
if (id(g_exp_f) > 0) { id(g_exp_f)--; if (id(g_exp_f)==0) id(g_exp_hide)=true; }
id(g_tcount)++; if (id(g_tcount) % 10 == 0) id(g_sw_score)++;
// auto-fire every 5 ticks into a free slot
id(g_fire)++;
if (id(g_fire) >= 5) { id(g_fire)=0; for(int i=0;i<2;i++){ if(!id(g_b_on)[i]){ id(g_b_on)[i]=true; id(g_b_x)[i]=px; id(g_b_y)[i]=100; break; } } }
// player bullets go up
for (int i=0;i<2;i++){ if(id(g_b_on)[i]){ id(g_b_y)[i]-=24; if(id(g_b_y)[i]<-185) id(g_b_on)[i]=false; } }
// enemies go down; destroyed/escaped -> respawn at the top
for (int e=0;e<3;e++){
if(id(g_en_on)[e]){ id(g_en_y)[e]+=6; if(id(g_en_y)[e]>188){ id(g_en_y)[e]=-160; id(g_en_x)[e]=(int)(esp_random()%280)-140; } }
else { id(g_en_on)[e]=true; id(g_en_y)[e]=-160-(int)(esp_random()%140); id(g_en_x)[e]=(int)(esp_random()%280)-140; }
}
// enemies shoot
if ((int)(esp_random()%100) < 9) { int k=(int)(esp_random()%3); if(id(g_en_on)[k]) for(int i=0;i<2;i++){ if(!id(g_eb_on)[i]){ id(g_eb_on)[i]=true; id(g_eb_x)[i]=id(g_en_x)[k]; id(g_eb_y)[i]=id(g_en_y)[k]+26; break; } } }
// enemy bullets go down
for (int i=0;i<2;i++){ if(id(g_eb_on)[i]){ id(g_eb_y)[i]+=13; if(id(g_eb_y)[i]>188) id(g_eb_on)[i]=false; } }
// player bullet x enemy
for (int b=0;b<2;b++){ if(id(g_b_on)[b]) for(int e=0;e<3;e++){ if(id(g_en_on)[e] && abs(id(g_b_x)[b]-id(g_en_x)[e])<22 && abs(id(g_b_y)[b]-id(g_en_y)[e])<26){ id(g_en_on)[e]=false; id(g_b_on)[b]=false; id(g_sw_score)+=10; id(g_exp_x)=id(g_en_x)[e]; id(g_exp_y)=id(g_en_y)[e]; id(g_exp_f)=6; id(g_exp_new)=true; break; } } }
// enemy / enemy bullet x player
id(g_sw_crash)=false;
if (id(g_sw_inv)<=0){
for(int e=0;e<3;e++){ if(id(g_en_on)[e] && abs(id(g_en_x)[e]-px)<26 && abs(id(g_en_y)[e]-130)<32){ id(g_en_on)[e]=false; id(g_sw_crash)=true; break; } }
for(int i=0;i<2;i++){ if(id(g_eb_on)[i] && abs(id(g_eb_x)[i]-px)<18 && abs(id(g_eb_y)[i]-130)<26){ id(g_eb_on)[i]=false; id(g_sw_crash)=true; break; } }
}
- lvgl.widget.update: { id: sw_ship, x: !lambda 'return id(g_sw_px);' }
- if: { condition: { lambda: 'return id(g_sw_crash);' }, then: [ script.execute: sw_lose ] }
# explosion after destroying an enemy: set position, show, run the animation once
- if:
condition: { lambda: 'return id(g_exp_new);' }
then:
- lvgl.widget.update: { id: sw_exp, x: !lambda 'return id(g_exp_x);', y: !lambda 'return id(g_exp_y);', hidden: false }
- lvgl.animimg.start: sw_exp
- lambda: 'id(g_exp_new)=false;'
- if:
condition: { lambda: 'return id(g_exp_hide);' }
then:
- lvgl.animimg.stop: sw_exp
- lvgl.widget.hide: sw_exp
- lambda: 'id(g_exp_hide)=false;'
# positions + visibility
- lvgl.widget.update: { id: b0, x: !lambda 'return id(g_b_x)[0];', y: !lambda 'return id(g_b_y)[0];', hidden: !lambda 'return !id(g_b_on)[0];' }
- lvgl.widget.update: { id: b1, x: !lambda 'return id(g_b_x)[1];', y: !lambda 'return id(g_b_y)[1];', hidden: !lambda 'return !id(g_b_on)[1];' }
- lvgl.widget.update: { id: eb0, x: !lambda 'return id(g_eb_x)[0];', y: !lambda 'return id(g_eb_y)[0];', hidden: !lambda 'return !id(g_eb_on)[0];' }
- lvgl.widget.update: { id: eb1, x: !lambda 'return id(g_eb_x)[1];', y: !lambda 'return id(g_eb_y)[1];', hidden: !lambda 'return !id(g_eb_on)[1];' }
- lvgl.widget.update: { id: en0, x: !lambda 'return id(g_en_x)[0];', y: !lambda 'return id(g_en_y)[0];', hidden: !lambda 'return !id(g_en_on)[0];' }
- lvgl.widget.update: { id: en1, x: !lambda 'return id(g_en_x)[1];', y: !lambda 'return id(g_en_y)[1];', hidden: !lambda 'return !id(g_en_on)[1];' }
- lvgl.widget.update: { id: en2, x: !lambda 'return id(g_en_x)[2];', y: !lambda 'return id(g_en_y)[2];', hidden: !lambda 'return !id(g_en_on)[2];' }
- lvgl.label.update: { id: lbl_sw_score, text: !lambda 'char b[12]; snprintf(b,sizeof(b),"%d",id(g_sw_score)); return std::string(b);' }
- if:
condition: { lambda: 'return id(g_sw_inv) > 0;' }
then:
- lvgl.widget.update: { id: sw_ship, hidden: !lambda 'return (id(g_sw_inv) % 4) >= 2;' }
- lvgl.widget.update: { id: sw_flash, hidden: !lambda 'return id(g_sw_inv) < 12;' }
image:
# Space Wars
- id: img_spacebg
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/spacebg.png"
type: RGB565
- id: img_logo2
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/logo2.png"
type: RGB565
- id: img_sp
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/player.png"
type: RGB565
transparency: alpha_channel
- id: img_se1
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/enemy1.png"
type: RGB565
transparency: alpha_channel
- id: img_se2
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/enemy2.png"
type: RGB565
transparency: alpha_channel
- id: img_exp0
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/exp0.png"
type: RGB565
transparency: alpha_channel
- id: img_exp1
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/exp1.png"
type: RGB565
transparency: alpha_channel
- id: img_exp2
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/exp2.png"
type: RGB565
transparency: alpha_channel
- id: img_exp3
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/exp3.png"
type: RGB565
transparency: alpha_channel
- id: img_exp4
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/exp4.png"
type: RGB565
transparency: alpha_channel
- id: img_exp5
file: "https://raw.githubusercontent.com/MichalZaniewicz/esphome-guition-jc3636k718c-va/main/assets/sprites/space-wars/exp5.png"
type: RGB565
transparency: alpha_channel
lvgl:
pages:
# --- SPACE WARS page (game 2): vertical shooter ---
- id: page_game2
bg_color: 0x140A20
scrollbar_mode: "off"
scrollable: false
widgets:
- image: { id: sw_bg, align: CENTER, x: 0, y: 0, src: img_spacebg, hidden: true }
- image: { id: sw_logo, align: CENTER, x: 0, y: 0, src: img_logo2, hidden: true }
- obj: { id: b0, align: CENTER, x: 0, y: 0, width: 4, height: 14, radius: 2, border_width: 0, bg_color: 0xFFE45A, hidden: true }
- obj: { id: b1, align: CENTER, x: 0, y: 0, width: 4, height: 14, radius: 2, border_width: 0, bg_color: 0xFFE45A, hidden: true }
- obj: { id: eb0, align: CENTER, x: 0, y: 0, width: 5, height: 14, radius: 2, border_width: 0, bg_color: 0xFF5050, hidden: true }
- obj: { id: eb1, align: CENTER, x: 0, y: 0, width: 5, height: 14, radius: 2, border_width: 0, bg_color: 0xFF5050, hidden: true }
- image: { id: en0, align: CENTER, x: -60, y: -150, src: img_se1, hidden: true }
- image: { id: en1, align: CENTER, x: 60, y: -150, src: img_se1, hidden: true }
- image: { id: en2, align: CENTER, x: 0, y: -150, src: img_se2, hidden: true }
- image: { id: sw_ship, align: CENTER, x: 0, y: 130, src: img_sp, hidden: true }
- animimg:
id: sw_exp
align: CENTER
x: 0
y: 0
src: [img_exp0, img_exp1, img_exp2, img_exp3, img_exp4, img_exp5]
duration: 420ms
repeat_count: 1
auto_start: false
hidden: true
- label: { id: lbl_sw_lives, align: CENTER, x: -54, y: -132, text: "", text_font: icons18, text_color: 0xE24B4A, hidden: true }
- label: { id: lbl_sw_score, align: CENTER, x: 54, y: -132, text: "0", text_font: font_med, text_color: 0xCFEAE4, hidden: true }
- obj: { id: sw_flash, align: CENTER, x: 0, y: 0, width: 360, height: 360, radius: 0, border_width: 0, bg_color: 0xFF2A2A, bg_opa: 45%, hidden: true }
# MENU
- button:
id: btn_sw_start
align: CENTER
y: 4
width: 150
height: 44
radius: 22
bg_color: 0xFF7A4D
bg_opa: COVER
border_width: 0
on_click: [ script.execute: sw_start ]
widgets: [ label: { align: CENTER, text: "Start", text_font: font_med, text_color: 0x2A0E06 } ]
- button:
id: btn_sw_howto
align: CENTER
y: 54
width: 150
height: 44
radius: 22
bg_color: 0x3A2150
bg_opa: COVER
border_width: 0
on_click: [ lambda: 'id(g_sw_state)=3;', script.execute: sw_screen ]
widgets: [ label: { align: CENTER, text: "How to play?", text_font: font_med, text_color: 0xFFFFFF } ]
- button:
id: btn_sw_scores
align: CENTER
y: 104
width: 150
height: 44
radius: 22
bg_color: 0x3A2150
bg_opa: COVER
border_width: 0
on_click: [ lambda: 'id(g_sw_state)=4;', script.execute: sw_screen ]
widgets: [ label: { align: CENTER, text: "Scores", text_font: font_med, text_color: 0xFFFFFF } ]
# GAME OVER
- label: { id: lbl_sw_over, align: CENTER, x: 0, y: -10, text_align: CENTER, text: "", text_font: font_sel, text_color: 0xFFFFFF, hidden: true }
- label: { id: lbl_sw_rec, align: CENTER, x: 0, y: 22, text_align: CENTER, text: "", text_font: font_artist, text_color: 0x9AA6B2, hidden: true }
- button:
id: btn_sw_replay
align: CENTER
x: -66
y: 62
width: 112
height: 48
radius: 24
bg_color: 0xFF7A4D
bg_opa: COVER
border_width: 0
hidden: true
on_click: [ script.execute: sw_start ]
widgets: [ label: { align: CENTER, text: "Play", text_font: font_med, text_color: 0x2A0E06 } ]
- button:
id: btn_sw_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_sw_state)=0;', script.execute: sw_screen ]
widgets: [ label: { align: CENTER, text: "Exit", text_font: font_med, text_color: 0xFFFFFF } ]
# HOW TO PLAY
- label: { id: lbl_sw_ht_t, align: CENTER, y: -104, text: "HOW TO PLAY?", text_font: font_sel, text_color: 0xFF7A4D, hidden: true }
- obj: { id: badge_h1, align: CENTER, x: -90, y: -46, width: 24, height: 24, radius: 12, bg_color: 0xFF7A4D, 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: badge_h2, align: CENTER, x: -90, y: -10, width: 24, height: 24, radius: 12, bg_color: 0xFF7A4D, 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: badge_h3, align: CENTER, x: -90, y: 26, width: 24, height: 24, radius: 12, bg_color: 0xFF7A4D, 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: badge_h4, align: CENTER, x: -90, y: 62, width: 24, height: 24, radius: 12, bg_color: 0xFF7A4D, bg_opa: COVER, border_width: 0, pad_all: 0, hidden: true, widgets: [ label: { align: CENTER, text: "4", text_font: font_artist, text_color: 0xFFFFFF } ] }
- label: { id: lbl_sw_ht1, align_to: { id: badge_h1, align: OUT_RIGHT_MID, x: 8 }, text: "Use the knob", text_font: font_med, text_color: 0xC2CDDA, hidden: true }
- label: { id: lbl_sw_ht2, align_to: { id: badge_h2, align: OUT_RIGHT_MID, x: 8 }, text: "Dodge bullets", text_font: font_med, text_color: 0xC2CDDA, hidden: true }
- label: { id: lbl_sw_ht3, align_to: { id: badge_h3, align: OUT_RIGHT_MID, x: 8 }, text: "Destroy enemies", text_font: font_med, text_color: 0xC2CDDA, hidden: true }
- label: { id: lbl_sw_ht4, align_to: { id: badge_h4, align: OUT_RIGHT_MID, x: 8 }, text: "You have 3 lives", text_font: font_med, text_color: 0xC2CDDA, hidden: true }
- label: { id: lbl_sw_hheart, align_to: { id: lbl_sw_ht4, align: OUT_RIGHT_MID, x: 6 }, text: "󰋑󰋑󰋑", text_font: icons18, text_color: 0xE24B4A, hidden: true }
# SCORES
- label: { id: lbl_sw_st, align: CENTER, y: -116, text: "SCORES", text_font: font_sel, text_color: 0xFF7A4D, hidden: true }
- label: { id: lbl_sw_s1, align: CENTER, x: -50, y: -6, text: "", text_align: LEFT, text_font: font_artist, text_color: 0xC2CDDA, hidden: true }
- label: { id: lbl_sw_s2, align: CENTER, x: 50, y: -6, text: "", text_align: LEFT, text_font: font_artist, text_color: 0xC2CDDA, hidden: true }
- button:
id: btn_sw_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_sw_state)=0;', script.execute: sw_screen ]
widgets: [ label: { align: CENTER, text: "Back", text_font: font_med, text_color: 0xFFFFFF } ]