234 lines
10 KiB
Python
234 lines
10 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
|
|
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
|