Files
tetri5/tetri5/scene.py
2021-07-08 01:20:33 -04:00

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