tildagon-scoreboard/tildagon-app/app.py
2024-11-07 19:28:13 +00:00

182 lines
5.1 KiB
Python

import time
from app_components import Menu, clear_background
from app_components.tokens import button_labels
from events.input import BUTTON_TYPES, Buttons
from perf_timer import PerfTimer
import app
WHITE_COLOR = (255, 255, 255)
BLACK_COLOR = (0, 0, 0)
TEAM_A_COLOR = (255, 107, 107)
TEAM_B_COLOR = (51, 154, 240)
BTN_LABEL_MODE = "Mode"
BTN_LABEL_RESET = "Reset"
BTN_LABEL_TEAM_A = "<-"
BTN_LABEL_TEAM_B = "->"
BTN_LABEL_SETTINGS = "..."
MENU_ITEM_SET_WIN_COND_11 = "Win pts = 11"
MENU_ITEM_SET_WIN_COND_21 = "Win pts = 21"
MENU_ITEM_QUIT = "Quit"
MODE_INCREMENT = "Increment"
MODE_DECREMENT = "Decrement"
class Scoreboard(app.App):
win_points = 11
a_score = 18
b_score = 18
mode = MODE_INCREMENT
settings_menu = None
winner = None
def __init__(self):
super().__init__()
self.button_states = Buttons(self)
def select_handler(self, item, index):
if item == MENU_ITEM_QUIT:
self.back_handler()
self.minimise()
self.button_states.clear()
elif item == MENU_ITEM_SET_WIN_COND_11:
self.win_points = 11
elif item == MENU_ITEM_SET_WIN_COND_21:
self.win_points = 21
# close menu
self.back_handler()
def back_handler(self):
if self.settings_menu is not None:
self.settings_menu._cleanup()
self.settings_menu = None
self.button_states.clear()
async def run(self, render_update):
last_time = time.ticks_ms()
while True:
cur_time = time.ticks_ms()
delta_ticks = time.ticks_diff(cur_time, last_time)
with PerfTimer(f"Updating {self}"):
self.update(delta_ticks)
await render_update()
last_time = cur_time
def check_win_condition(self):
diff = abs(self.a_score - self.b_score)
if (
self.a_score >= self.win_points
and self.a_score > self.b_score
and diff >= 2
):
self.winner = "a"
elif (
self.b_score >= self.win_points
and self.b_score > self.a_score
and diff >= 2
):
self.winner = "b"
else:
self.winner = None
def update(self, delta):
if self.settings_menu is not None:
self.settings_menu.update(delta)
return
if self.button_states.get(BUTTON_TYPES["UP"]):
if self.mode == MODE_INCREMENT:
self.mode = MODE_DECREMENT
else:
self.mode = MODE_INCREMENT
self.button_states.clear()
if self.button_states.get(BUTTON_TYPES["DOWN"]):
self.a_score = 0
self.b_score = 0
self.mode = MODE_INCREMENT
self.winner = None
self.button_states.clear()
if self.button_states.get(BUTTON_TYPES["LEFT"]):
if self.mode == MODE_INCREMENT:
self.a_score += 1
elif self.mode == MODE_DECREMENT and self.a_score > 0:
self.a_score -= 1
self.check_win_condition()
self.button_states.clear()
if self.button_states.get(BUTTON_TYPES["RIGHT"]):
if self.mode == MODE_INCREMENT:
self.b_score += 1
elif self.mode == MODE_DECREMENT and self.b_score > 0:
self.b_score -= 1
self.check_win_condition()
self.button_states.clear()
if self.button_states.get(BUTTON_TYPES["CONFIRM"]):
self.settings_menu = Menu(
self,
menu_items=[
MENU_ITEM_SET_WIN_COND_11,
MENU_ITEM_SET_WIN_COND_21,
MENU_ITEM_QUIT,
],
select_handler=self.select_handler,
back_handler=self.back_handler,
)
self.button_states.clear()
def draw(self, ctx):
clear_background(ctx)
if self.settings_menu is not None:
self.settings_menu.draw(ctx)
return
bg_color = BLACK_COLOR
fg_color = WHITE_COLOR
team_a_fg = TEAM_A_COLOR
team_b_fg = TEAM_B_COLOR
if self.winner is not None:
bg_color = TEAM_A_COLOR if self.winner == "a" else TEAM_B_COLOR
fg_color = BLACK_COLOR
team_a_fg = TEAM_A_COLOR if self.winner == "b" else fg_color
team_b_fg = TEAM_B_COLOR if self.winner == "a" else fg_color
ctx.rgb(*bg_color).rectangle(-120, -120, 240, 240).fill()
button_labels(
ctx,
up_label=self.mode,
down_label=BTN_LABEL_RESET,
left_label=BTN_LABEL_TEAM_A,
right_label=BTN_LABEL_TEAM_B,
confirm_label=BTN_LABEL_SETTINGS,
)
ctx.text_align = ctx.CENTER
ctx.font_size = 20
ctx.font = "Arimo Bold"
ctx.rgb(*fg_color).move_to(0, 60).text(f"w={self.win_points}")
ctx.font_size = 96
ctx.font = "Arimo Bold"
ctx.rgb(*team_a_fg).move_to(-50, 0).text(self.a_score)
ctx.rgb(*team_b_fg).move_to(50, 0).text(self.b_score)
self.draw_overlays(ctx)
__app_export__ = Scoreboard