72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
|
from typing import Any
|
||
|
import pygame as pg
|
||
|
|
||
|
from .settings import *
|
||
|
|
||
|
|
||
|
class App:
|
||
|
def __init__(self) -> None:
|
||
|
from .tetris import Tetris
|
||
|
|
||
|
# TODO: dynamic timeout
|
||
|
self.fall_timeout: Generator[int, Any, Any] = FALL_TIMEOUT_GENERATOR
|
||
|
self.paused = False
|
||
|
|
||
|
pg.init()
|
||
|
pg.display.set_caption(CAPTION)
|
||
|
self.init_event_timer()
|
||
|
self.screen = pg.display.set_mode(FIELD_RES)
|
||
|
self.clock = pg.time.Clock()
|
||
|
self.tetris = Tetris(self)
|
||
|
|
||
|
def init_event_timer(self):
|
||
|
# when timeout, set trigger to true to make tetromino fall
|
||
|
self.fall_trigger = False
|
||
|
self.fall_event = pg.USEREVENT
|
||
|
pg.time.set_timer(self.fall_event, next(self.fall_timeout))
|
||
|
|
||
|
def update(self):
|
||
|
self.tetris.update()
|
||
|
self.clock.tick(FPS)
|
||
|
|
||
|
def draw(self):
|
||
|
'''
|
||
|
main app frame drawer. This method only run once.
|
||
|
draw app background color
|
||
|
draw tetris grids
|
||
|
'''
|
||
|
self.screen.fill(color=FIELD_COLOR, rect=(0, 0, *FIELD_RES))
|
||
|
self.tetris.draw() # draw grid
|
||
|
pg.display.flip()
|
||
|
|
||
|
def check_events(self):
|
||
|
'''
|
||
|
Main event loop.
|
||
|
'''
|
||
|
self.fall_trigger = False # fall_event set in set_event_timer
|
||
|
for event in pg.event.get():
|
||
|
if event.type == pg.QUIT or (
|
||
|
event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE
|
||
|
or event.type == pg.KEYDOWN and event.key == pg.K_c
|
||
|
and pg.key.get_mods() & pg.KMOD_CTRL
|
||
|
): # handle ctrl+c, https://stackoverflow.com/a/46506753/20419707
|
||
|
pg.quit()
|
||
|
exit()
|
||
|
elif event.type == pg.KEYDOWN:
|
||
|
if event.key == pg.K_p:
|
||
|
self.paused = not self.paused
|
||
|
elif not self.paused:
|
||
|
self.tetris.control(event.key)
|
||
|
elif event.type == self.fall_event and not self.paused:
|
||
|
self.fall_trigger = True
|
||
|
pg.time.set_timer(self.fall_event, next(self.fall_timeout))
|
||
|
|
||
|
def run(self):
|
||
|
'''
|
||
|
Main loop.
|
||
|
'''
|
||
|
while True:
|
||
|
self.check_events()
|
||
|
self.update()
|
||
|
self.draw()
|