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 from tetri5.online import MultiplayerService """ 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_pos_one = ConfigurationManager.get("position", "cursor-option-one") self._cursor_pos_two = ConfigurationManager.get("position", "cursor-option-two") self._cursor_pos = self._cursor_pos_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_pos = ConfigurationManager.get("position", "title-logo") self._option_one_pos = ConfigurationManager.get("position", "option-one") self._option_two_pos = 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_pos) TextGenerator.draw(TitleScene.ONE_PLAYER, self._option_one_pos, surface) TextGenerator.draw(TitleScene.TWO_PLAYER, self._option_two_pos, surface) if self._cursor_off: pygame.draw.circle(surface, self._cursor_color, self._cursor_pos, 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_pos = self._cursor_pos_one self._is_multiplayer = False option_change = True if Controller.key_pressed(pygame.K_DOWN) and not self._is_multiplayer: self._cursor_pos = self._cursor_pos_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) if not self._is_multiplayer else MultiPlayerScene(self._change_scence)) """ TODO """ class SinglePlayerScene(Scene): def __init__(self, change_scene: FunctionType) -> None: self._top_label_pos = ConfigurationManager.get("position", "top-label") self._top_value_pos = ConfigurationManager.get("position", "top-value") self._score_label_pos = ConfigurationManager.get("position", "score-label") self._score_value_pos = ConfigurationManager.get("position", "score-value") self._lines_label_pos = ConfigurationManager.get("position", "lines-label") self._next_label_pos = ConfigurationManager.get("position", "next-label") self._level_label_pos = ConfigurationManager.get("position", "level-label") self._next_piece_pos = ConfigurationManager.get("position", "next-piece") self._spawn_piece_shift = ConfigurationManager.get("position", "spawn-piece") self._tile_size = ConfigurationManager.get("engine", "tile-size") self._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg")) self._points_table = ConfigurationManager.get("engine", "points-table") self._lines_per_level = ConfigurationManager.get("engine", "lines-per-level") self._score = 0 self._previous_level = 0 self._current_piece = None self._next_piece = PieceGenerator.get_piece(self._next_piece_pos) self._well = Well(ConfigurationManager.get("position", "well"),\ ConfigurationManager.get("color", "well-1"),\ ConfigurationManager.get("color", "well-border-1")) self._stack = Stack() 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", self._top_label_pos, surface) TextGenerator.draw("000000", self._top_value_pos, surface) TextGenerator.draw("Score", self._score_label_pos, surface) TextGenerator.draw(score, self._score_value_pos, surface) TextGenerator.draw("Lines " + lines, self._lines_label_pos, surface) TextGenerator.draw("Next", self._next_label_pos, surface) TextGenerator.draw("LVL " + level, self._level_label_pos, 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(self._spawn_piece_shift) self._next_piece = PieceGenerator.get_piece(self._next_piece_pos) # TODO create game over scene if self._stack and self._current_piece.collide(self._stack): 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: return 0 if not self._stack else self._stack.total_lines // self._lines_per_level def _clear_current_piece(self) -> None: self._current_piece = None """ TODO """ class MultiPlayerScene(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")) # wells init self._well_player_one = Well(ConfigurationManager.get("position", "well-player-1"),\ ConfigurationManager.get("color", "well-1"),\ ConfigurationManager.get("color", "well-border-1")) self._well_player_two = Well(ConfigurationManager.get("position", "well-player-2"),\ ConfigurationManager.get("color", "well-1"),\ ConfigurationManager.get("color", "well-border-1")) # stacks init self._stack_player_one = Stack() self._stack_player_two = Stack() # score positions self.score_label_player_one_pos = ConfigurationManager.get("position", "score-label-player-1") self.score_label_player_two_pos = ConfigurationManager.get("position", "score-label-player-2") self.score_value_player_one_pos = ConfigurationManager.get("position", "score-value-player-1") self.score_value_player_two_pos = ConfigurationManager.get("position", "score-value-player-2") # lines positions self.lines_label_player_one_pos = ConfigurationManager.get("position", "lines-label-player-1") self.lines_label_player_two_pos = ConfigurationManager.get("position", "lines-label-player-2") # next positions self.next_label_player_one_pos = ConfigurationManager.get("position", "next-label-player-1") self.next_label_player_two_pos = ConfigurationManager.get("position", "next-label-player-2") self._change_scence = change_scene MultiplayerService.init() def draw(self, surface: pygame.Surface) -> None: surface.fill(self._background_color) # wells if self._well_player_one: self._well_player_one.draw(surface) if self._well_player_two: self._well_player_two.draw(surface) # stacks if self._stack_player_one: self._stack_player_one.draw(surface) if self._stack_player_two: self._stack_player_two.draw(surface) # scores TextGenerator.draw("Score", self.score_label_player_one_pos, surface) TextGenerator.draw("000000", self.score_value_player_one_pos, surface) TextGenerator.draw("Score", self.score_label_player_two_pos, surface) TextGenerator.draw("000000", self.score_value_player_two_pos, surface) # lines TextGenerator.draw("Lines 0000", self.lines_label_player_one_pos, surface) TextGenerator.draw("Lines 0000", self.lines_label_player_two_pos, surface) # next TextGenerator.draw("P1 NXT", self.next_label_player_one_pos, surface) TextGenerator.draw("P2 NXT", self.next_label_player_two_pos, surface) def update(self, elapsed_time: int) -> None: pass