Files
tetri5/tetri5/scene.py
2021-07-08 11:23:47 -04:00

154 lines
6.3 KiB
Python

import sys
import pygame
from types import FunctionType
from tetri5.util import ConfigurationManager
from tetri5.util import TextGenerator
from tetri5.util import Controller
from tetri5.util import SoundManager
from tetri5.entity import Well
from tetri5.entity import Stack
from tetri5.entity import PieceGenerator
"""
TODO
"""
class Scene:
pass
"""
TODO
"""
class TitleScene(Scene):
# Title screen options
ONE_PLAYER = "1 PLAYER"
TWO_PLAYER = "2 PLAYER"
def __init__(self, change_scene: FunctionType) -> None:
self._tile_size = ConfigurationManager.get("engine", "tile-size")
self._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg"))
self._logo_image = pygame.image.load(ConfigurationManager.get("image", "title-screen"))
self._cursor_position_one = ConfigurationManager.get("position", "cursor-option-one")
self._cursor_position_two = ConfigurationManager.get("position", "cursor-option-two")
self._cursor_position = self._cursor_position_one
self._cursor_blink_interval = ConfigurationManager.get("engine", "cursor-blink-interval")
self._cursor_blink_time = 0
self._cursor_color = pygame.Color(ConfigurationManager.get("color", "cursor"))
self._cursor_off = False
self._logo_position = ConfigurationManager.get("position", "title-logo")
self._option_one_position = ConfigurationManager.get("position", "option-one")
self._option_two_position = ConfigurationManager.get("position", "option-two")
self._is_multiplayer = False
self._change_scence = change_scene
def draw(self, surface: pygame.Surface) -> None:
surface.fill(self._background_color)
surface.blit(self._logo_image, self._logo_position)
TextGenerator.draw(TitleScene.ONE_PLAYER, self._option_one_position, surface)
TextGenerator.draw(TitleScene.TWO_PLAYER, self._option_two_position, surface)
if self._cursor_off:
pygame.draw.circle(surface, self._cursor_color, self._cursor_position, self._tile_size // 3)
def update(self, elapsed_time: int) -> None:
option_change = False
if Controller.key_pressed(pygame.K_UP) and self._is_multiplayer:
self._cursor_position = self._cursor_position_one
self._is_multiplayer = False
option_change = True
if Controller.key_pressed(pygame.K_DOWN) and not self._is_multiplayer:
self._cursor_position = self._cursor_position_two
self._is_multiplayer = True
option_change = True
if option_change:
SoundManager.play_option_change_sfx() # TODO add cool down
self._cursor_blink_time += elapsed_time
if self._cursor_blink_time >= self._cursor_blink_interval:
self._cursor_blink_time = 0
self._cursor_off = not self._cursor_off
if Controller.key_pressed(pygame.K_RETURN):
self._change_scence(SinglePlayerScene(self._change_scence)) # TODO implement multiplayer
"""
TODO
"""
class SinglePlayerScene(Scene):
def __init__(self, change_scene: FunctionType) -> None:
self._tile_size = ConfigurationManager.get("engine", "tile-size")
self._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg"))
self._score = 0
self._previous_level = 0
self._well = Well((280, 80), ConfigurationManager.get("color", "well-1"), ConfigurationManager.get("color", "well-border-1")) # TODO calculate position later and redo color config for well
self._stack = Stack(ConfigurationManager.get("color", "stack-1"), ConfigurationManager.get("color", "stack-border-1"))
self._current_piece = None
self._next_piece = PieceGenerator.get_piece((620, 160))
self._points_table = ConfigurationManager.get("engine", "points-table")
self._change_scence = change_scene
SoundManager.play_theme_music()
def draw(self, surface: pygame.Surface) -> None:
surface.fill(self._background_color)
if self._next_piece:
self._next_piece.draw(surface)
if self._well:
self._well.draw(surface)
if self._stack:
self._stack.draw(surface)
if self._current_piece:
self._current_piece.draw(surface, self._well, self._stack)
score = str(self._score).zfill(6)
lines = str(self._stack.total_lines).zfill(4)
level = str(self._get_level()).zfill(2)
TextGenerator.draw("Top", (80, 120), surface)
TextGenerator.draw("000000", (80, 140), surface)
TextGenerator.draw("Score", (80, 180), surface)
TextGenerator.draw(score, (80, 200), surface)
TextGenerator.draw("Lines " + lines, (300, 40), surface)
TextGenerator.draw("Next", (600, 120), surface)
TextGenerator.draw("LVL " + level, (600, 220), surface)
def update(self, elapsed_time: int) -> None:
if self._current_piece:
self._current_piece.update(elapsed_time,\
self._well,\
self._stack,\
self._get_level(),\
self._clear_current_piece)
else:
self._current_piece = self._next_piece
self._current_piece.move((360 - 620, 100 - 160)) # TODO calculate spawn position correctly
self._next_piece = PieceGenerator.get_piece((620, 160)) # (360, 100)
if self._stack and self._current_piece.collide(self._stack): # TODO game over redo
pygame.quit()
sys.exit()
if self._stack:
self._stack.update(elapsed_time)
self._score += self._points_table[self._stack.lines_completed_last] * (self._get_level() + 1)
if self._previous_level != self._get_level():
self._previous_level = self._get_level()
SoundManager.play_level_up_sfx()
def _get_level(self) -> int:
lines_per_level = ConfigurationManager.get("engine", "lines-per-level")
return 0 if not self._stack else self._stack.total_lines // lines_per_level
def _clear_current_piece(self) -> None:
self._current_piece = None
"""
TODO
"""
class MultiPlayerScene(Scene):
pass