CiscoTheProot/rpi/ProotState.py

95 lines
3.9 KiB
Python

from PIL import Image
class ProotState:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.current_blink_state = 0
cls._instance.desired_blink_state = 0
cls._instance.blinks_frames_ready = False
cls._instance.loading_screen = True
cls._instance.loading_time = 0
cls._instance.frame_canvas_prootScreen_1 = False
cls._instance.frame_canvas_prootScreen_2 = False
cls._instance.frame_canvas_prootScreen_3 = False
cls._instance.matrix = False
cls._instance.bean_states = [False] * 4
cls._instance.desired_face = 0 # 0=default, 1=blink, 2=owo, 3=angry
return cls._instance
def set_matrix(self, matrix):
self.matrix = matrix
def next_blink_frame_number(self) -> int:
if self.current_blink_state == self.desired_blink_state == 10:
self.desired_blink_state = 0
return self.current_blink_state
if self.current_blink_state == self.desired_blink_state == 0:
return self.current_blink_state
if self.current_blink_state < self.desired_blink_state:
self.current_blink_state += 1
else:
self.current_blink_state -= 1
return self.current_blink_state
def blink(self, state = 10):
self.set_desired_blink_state(state)
def set_desired_blink_state(self, state: int):
self.desired_blink_state = state
def set_blinks_frames_ready(self, ready: bool):
self.blinks_frames_ready = ready
def get_desired_blink_state(self) -> int:
return self.desired_blink_state
def get_blinks_frames_ready(self) -> bool:
return self.blinks_frames_ready
# This function animates the loading screen. It asumes that the function gets called frequently(every frame update)
def set_ProotScreen(self, matrix):
self.loading_time += 1
self.loading_time = self.loading_time % 75
if not self.frame_canvas_prootScreen_1:
self.frame_canvas_prootScreen_1 = matrix.CreateFrameCanvas()
image_proot_screen_1 = Image.open("faces/ProotScreen1.png").convert('RGB')
self.frame_canvas_prootScreen_1.SetImage(image_proot_screen_1, unsafe=False)
matrix.SwapOnVSync(self.frame_canvas_prootScreen_1)
if not self.frame_canvas_prootScreen_2:
self.frame_canvas_prootScreen_2 = matrix.CreateFrameCanvas()
image_proot_screen_2 = Image.open("faces/ProotScreen2.png").convert('RGB')
self.frame_canvas_prootScreen_2.SetImage(image_proot_screen_2, unsafe=False)
matrix.SwapOnVSync(self.frame_canvas_prootScreen_2)
if not self.frame_canvas_prootScreen_3:
self.frame_canvas_prootScreen_3 = matrix.CreateFrameCanvas()
image_proot_screen_3 = Image.open("faces/ProotScreen3.png").convert('RGB')
self.frame_canvas_prootScreen_3.SetImage(image_proot_screen_3, unsafe=False)
matrix.SwapOnVSync(self.frame_canvas_prootScreen_3)
if self.loading_time < 25:
matrix.SwapOnVSync(self.frame_canvas_prootScreen_1)
elif self.loading_time < 50:
matrix.SwapOnVSync(self.frame_canvas_prootScreen_2)
else:
matrix.SwapOnVSync(self.frame_canvas_prootScreen_3)
def set_bean(self, bean_number, bean_state):
self.bean_states[bean_number] = bean_state
def update_screen(self, blinkFrameCanvases, matrix):
proot_state = ProotState()
if proot_state.get_blinks_frames_ready():
# TODO move blinking animation writing logic to the ProotState class
matrix.SwapOnVSync(blinkFrameCanvases[proot_state.next_blink_frame_number()])
else:
proot_state.set_ProotScreen(matrix)