148 lines
6.0 KiB
Python
148 lines
6.0 KiB
Python
import sys
|
|
import pygame
|
|
from pygame import mixer
|
|
from types import FunctionType
|
|
from tetri5.util import ConfigurationManager
|
|
from tetri5.util import TextGenerator
|
|
from tetri5.util import Controller
|
|
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:
|
|
if Controller.key_pressed(pygame.K_UP):
|
|
self._cursor_position = self._cursor_position_one
|
|
self._is_multiplayer = False
|
|
if Controller.key_pressed(pygame.K_DOWN):
|
|
self._cursor_position = self._cursor_position_two
|
|
self._is_multiplayer = True
|
|
|
|
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
|
|
"""
|
|
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._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._main_music = mixer.Channel(0)
|
|
self._main_music.set_volume(0.7) # TODO add volume to the config
|
|
self._main_music.play(mixer.Sound(ConfigurationManager.get("sound", "main-music")), -1)
|
|
self._points_table = ConfigurationManager.get("engine", "points-table")
|
|
|
|
self._change_scence = change_scene
|
|
|
|
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)
|
|
|
|
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
|