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:
width: 800
height: 600
title: "Tetris"
title: "Tetri5"
sound:
main-music: "resource/sound/main_music.wav"
main-music: "resource/sound/main_music.ogg"
row-completion: "resource/sound/row_completion.wav"
piece-set: "resource/sound/piece_set_3.wav"
@@ -14,9 +13,17 @@ image:
window-icon: "resource/image/tetris_icon.png"
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:
fps: 60
tile-size: 20
cursor-blink-interval: 150
piece-gravity-time: 600
piece-set-time: 600
piece-gravity-increase: 56
@@ -29,7 +36,11 @@ engine:
- 1200 # 4 lines
color:
# window
window-bg: "#000000"
# title screen
cursor: "#FFFFFF"
# in game
piece-1: "#1F37EC"
piece-2: "#3DBBFC"
piece-3: "#FFFFFF"

View File

@@ -4,14 +4,14 @@
https://tetris.com/play-tetris
'''
from tetris.game import Game
from tetris.util import ConfigurationManager
from tetri5.game import Game
from tetri5.util import ConfigurationManager
def main() -> None:
ConfigurationManager. init()
ConfigurationManager.init()
game = Game()
game.initialize()
game.init()
while True:
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
from typing import List, Tuple
from pygame import mixer
from tetris.util import ConfigurationManager
from tetris.util import Controller
from tetri5.util import ConfigurationManager
from tetri5.util import Controller
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from tetris.game import Game
from tetri5.game import Game
"""
TODO description
@@ -65,11 +65,11 @@ class Well(Entity):
shape = []
for i in range(self.WIDTH + 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)))
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)))
points = []
for square in shape:
sub_points = []

View File

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

View File

@@ -100,7 +100,7 @@ class _NetworkConnectionService():
@classmethod
async def _try_receive_message(cls) -> None:
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
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