feat!: add title screen scene

This commit is contained in:
2021-07-07 21:47:55 -04:00
parent 21c682b6aa
commit 123d1e7817
11 changed files with 111 additions and 67 deletions

View File

@@ -1,11 +1,10 @@
window: window:
width: 800 width: 800
height: 600 height: 600
title: "Tetri5"
title: "Tetris"
sound: sound:
main-music: "resource/sound/main_music.wav" main-music: "resource/sound/main_music.ogg"
row-completion: "resource/sound/row_completion.wav" row-completion: "resource/sound/row_completion.wav"
piece-set: "resource/sound/piece_set_3.wav" piece-set: "resource/sound/piece_set_3.wav"
@@ -14,9 +13,17 @@ image:
window-icon: "resource/image/tetris_icon.png" window-icon: "resource/image/tetris_icon.png"
font: "resource/image/press-start-2p-font.bmp" font: "resource/image/press-start-2p-font.bmp"
position:
title-logo: [280, 125]
option-one: [320, 390]
option-two: [320, 440]
cursor-option-one: [300, 399]
cursor-option-two: [300, 449]
engine: engine:
fps: 60 fps: 60
tile-size: 20 tile-size: 20
cursor-blink-interval: 150
piece-gravity-time: 600 piece-gravity-time: 600
piece-set-time: 600 piece-set-time: 600
piece-gravity-increase: 56 piece-gravity-increase: 56
@@ -29,7 +36,11 @@ engine:
- 1200 # 4 lines - 1200 # 4 lines
color: color:
# window
window-bg: "#000000" window-bg: "#000000"
# title screen
cursor: "#FFFFFF"
# in game
piece-1: "#1F37EC" piece-1: "#1F37EC"
piece-2: "#3DBBFC" piece-2: "#3DBBFC"
piece-3: "#FFFFFF" piece-3: "#FFFFFF"

View File

@@ -4,14 +4,14 @@
https://tetris.com/play-tetris https://tetris.com/play-tetris
''' '''
from tetris.game import Game from tetri5.game import Game
from tetris.util import ConfigurationManager from tetri5.util import ConfigurationManager
def main() -> None: def main() -> None:
ConfigurationManager. init() ConfigurationManager.init()
game = Game() game = Game()
game.initialize() game.init()
while True: while True:
game.update() game.update()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

View File

@@ -3,12 +3,12 @@ import random
import pygame import pygame
from typing import List, Tuple from typing import List, Tuple
from pygame import mixer from pygame import mixer
from tetris.util import ConfigurationManager from tetri5.util import ConfigurationManager
from tetris.util import Controller from tetri5.util import Controller
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from tetris.game import Game from tetri5.game import Game
""" """
TODO description TODO description
@@ -65,11 +65,11 @@ class Well(Entity):
shape = [] shape = []
for i in range(self.WIDTH + 2): for i in range(self.WIDTH + 2):
for j in range(self.HEIGHT + 2): for j in range(self.HEIGHT + 2):
if i == 0 or i == self.WIDTH + 1: if i in [0, self.WIDTH + 1]:
shape.append(((i, j), (i + 1, j), (i + 1, j + 1), (i, j + 1))) shape.append(((i, j), (i + 1, j), (i + 1, j + 1), (i, j + 1)))
elif j == 0 or j == self.HEIGHT + 1: elif j in [0, self.HEIGHT + 1]:
shape.append(((i, j), (i + 1, j), (i + 1, j + 1), (i, j + 1))) shape.append(((i, j), (i + 1, j), (i + 1, j + 1), (i, j + 1)))
points = [] points = []
for square in shape: for square in shape:
sub_points = [] sub_points = []

View File

@@ -1,13 +1,13 @@
import sys import sys
import pygame import pygame
from pygame import mixer from pygame import mixer
from tetris.util import ConfigurationManager from tetri5.util import ConfigurationManager
from tetris.util import TextGenerator from tetri5.util import TextGenerator
from tetris.entity import PieceGenerator from tetri5.entity import PieceGenerator
from tetris.entity import Well from tetri5.entity import Well
from tetris.entity import Stack from tetri5.entity import Stack
from tetris.online import MultiplayerService from tetri5.online import MultiplayerService
from tetris.scene import TitleScene from tetri5.scene import TitleScene
# TODO improve game assets https://www.spriters-resource.com/nes/tetris/ # TODO improve game assets https://www.spriters-resource.com/nes/tetris/
# TODO should be a singleton and refactor the whole file? # TODO should be a singleton and refactor the whole file?
@@ -18,7 +18,6 @@ class Game:
self.tile_size = -1 self.tile_size = -1
self.screen = None self.screen = None
self.clock = None self.clock = None
self.current_scene = TitleScene() self.current_scene = TitleScene()
# In Game # # In Game #
@@ -27,8 +26,9 @@ class Game:
self.well = None self.well = None
self.stack = None self.stack = None
self.main_music = None self.main_music = None
self.score = -1
def initialize(self) -> None: def init(self) -> None:
pygame.init() pygame.init()
TextGenerator.init(ConfigurationManager.get("image", "font"), (20, 20)) TextGenerator.init(ConfigurationManager.get("image", "font"), (20, 20))
@@ -41,28 +41,26 @@ class Game:
self.tile_size = ConfigurationManager.get("engine", "tile-size") self.tile_size = ConfigurationManager.get("engine", "tile-size")
self.screen = pygame.display.set_mode((win_width, win_height)) self.screen = pygame.display.set_mode((win_width, win_height))
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
pygame.display.set_caption(win_title)
pygame.display.set_icon(pygame.image.load(win_icon))
self.main_music = mixer.Channel(0) self.main_music = mixer.Channel(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.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.stack = Stack(ConfigurationManager.get("color", "stack-1"), ConfigurationManager.get("color", "stack-border-1"))
self.score = 0 self.score = 0
loaded_icon = pygame.image.load(win_icon)
pygame.display.set_caption(win_title)
pygame.display.set_icon(loaded_icon)
main_music_file = ConfigurationManager.get("sound", "main-music")
self.main_music.set_volume(0.7) # TODO add volume to the config self.main_music.set_volume(0.7) # TODO add volume to the config
self.main_music.play(mixer.Sound(main_music_file), -1) self.main_music.play(ConfigurationManager.get("sound", "main-music"), -1)
# gets called from the games main loop # gets called from the games main loop
def update(self) -> None: def update(self) -> None:
# TODO write not initialized exception
elapsed_time = self.clock.tick(self.fps)
if self.current_scene: if self.current_scene:
self.current_scene.update() self.current_scene.update(elapsed_time)
else: else:
# TODO write not initialized exception
elapsed_time = self.clock.tick(self.fps)
if not self.next_piece: if not self.next_piece:
self.next_piece = PieceGenerator.get_piece((620, 160)) self.next_piece = PieceGenerator.get_piece((620, 160))

View File

@@ -100,7 +100,7 @@ class _NetworkConnectionService():
@classmethod @classmethod
async def _try_receive_message(cls) -> None: async def _try_receive_message(cls) -> None:
try: try:
task = cls._pending_receive_task if cls._pending_receive_task else asyncio.create_task(cls._websocket.recv()) task = cls._pending_receive_task or asyncio.create_task(cls._websocket.recv())
done, pending = await asyncio.wait({task}, timeout=8e-3) # TODO experiment with the timeout done, pending = await asyncio.wait({task}, timeout=8e-3) # TODO experiment with the timeout
if task in done: if task in done:

68
tetri5/scene.py Normal file
View File

@@ -0,0 +1,68 @@
import pygame
from tetri5.util import ConfigurationManager
from tetri5.util import TextGenerator
from tetri5.util import Controller
"""
TODO
"""
class TitleScene:
# Title screen options
ONE_PLAYER = "1 PLAYER"
TWO_PLAYER = "2 PLAYER"
def __init__(self) -> None:
self._tile_size = ConfigurationManager.get("engine", "tile-size")
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._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg"))
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
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) -> 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
"""
TODO
"""
class SinglePlayerScene:
pass
"""
TODO
"""
class MultiPlayerScene:
pass

View File

@@ -1,33 +0,0 @@
import pygame
from tetris.util import ConfigurationManager
from tetris.util import TextGenerator
from tetris.util import Controller
"""
TODO
"""
class TitleScene:
# Title screen options
ONE_PLAYER = "ONE_PLAYER"
TWO_PLAYER = "TWO_PLAYER"
def __init__(self) -> None:
image_path = ConfigurationManager.get("image", "title-screen")
self.splash_image = pygame.image.load(image_path)
self.cursor_position = None
self.cursor_flash_timer = 0
def draw(self, screen) -> None:
screen.fill(pygame.Color(ConfigurationManager.get("color", "window-bg")))
screen.blit(self.splash_image, (300, 0))
TextGenerator.draw("1 PLAYER", (300, 400), screen)
TextGenerator.draw("2 PLAYER", (300, 450), screen)
def update(self) -> None:
if Controller.key_pressed(pygame.K_DOWN):
self.current_option = TitleScene.ONE_PLAYER
if Controller.key_pressed(pygame.K_UP):
self.current_option = TitleScene.TWO_PLAYER