feat: add game over modal
This commit is contained in:
@@ -4,13 +4,16 @@ window:
|
||||
title: "Tetri5"
|
||||
|
||||
sound:
|
||||
theme-music: "resource/sound/theme_music.ogg"
|
||||
theme-music-single: "resource/sound/theme_music_single.ogg"
|
||||
theme-music-multi: "resource/sound/theme_music_multi.ogg"
|
||||
option-change: "resource/sound/option_change.wav"
|
||||
piece-rotate: "resource/sound/piece_rotate.ogg"
|
||||
piece-set: "resource/sound/piece_set.ogg"
|
||||
line-complete: "resource/sound/line_complete.ogg"
|
||||
four-lines-complete: "resource/sound/four_lines_complete.ogg"
|
||||
level-up: "resource/sound/level_up.ogg"
|
||||
game-over: "resource/sound/game_over.ogg"
|
||||
you-win: "resource/sound/you_win.ogg"
|
||||
|
||||
image:
|
||||
title-screen: "resource/image/title_screen.png"
|
||||
|
||||
BIN
resource/sound/game_over.ogg
Normal file
BIN
resource/sound/game_over.ogg
Normal file
Binary file not shown.
BIN
resource/sound/theme_music_single.ogg
Normal file
BIN
resource/sound/theme_music_single.ogg
Normal file
Binary file not shown.
BIN
resource/sound/you_win.ogg
Normal file
BIN
resource/sound/you_win.ogg
Normal file
Binary file not shown.
27
tetri5/modal.py
Normal file
27
tetri5/modal.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import pygame
|
||||
from pygame import Surface
|
||||
from tetri5.util import SoundManager, TextGenerator
|
||||
|
||||
class GameOverModal:
|
||||
def __init__(self):
|
||||
self.is_open = False
|
||||
self.is_winner = False
|
||||
self.music_played = False
|
||||
|
||||
def show(self, is_winner: bool) -> None:
|
||||
self.is_open = True
|
||||
self.is_winner = is_winner
|
||||
|
||||
def draw(self, surface: Surface) -> None:
|
||||
pygame.draw.rect(surface, "black", pygame.Rect(290, 240, 220, 100))
|
||||
pygame.draw.rect(surface, "white", pygame.Rect(290, 240, 220, 100), 3, 5)
|
||||
TextGenerator.draw("YOU LOSE" if not self.is_winner else "YOU WIN!", (320, 260), surface)
|
||||
TextGenerator.draw("GAME OVER", (310, 300), surface)
|
||||
|
||||
def update(self, _: int) -> None:
|
||||
if not self.music_played:
|
||||
if self.is_winner:
|
||||
SoundManager.play_you_win_sfx()
|
||||
else:
|
||||
SoundManager.play_game_over_sfx()
|
||||
self.music_played = True
|
||||
@@ -9,6 +9,7 @@ from tetri5.entity import SquareColor, Well
|
||||
from tetri5.entity import Stack
|
||||
from tetri5.entity import PieceGenerator
|
||||
from tetri5.online import *
|
||||
from tetri5.modal import GameOverModal
|
||||
|
||||
"""
|
||||
TODO
|
||||
@@ -104,10 +105,16 @@ class SinglePlayerScene(Scene):
|
||||
ConfigurationManager.get("color", "well-border-1"))
|
||||
self._stack = Stack()
|
||||
|
||||
self._game_over_modal = GameOverModal()
|
||||
|
||||
self._change_scence = change_scene
|
||||
SoundManager.play_theme_music()
|
||||
SoundManager.play_theme_music_single()
|
||||
|
||||
def draw(self, surface: pygame.Surface) -> None:
|
||||
if self._game_over_modal.is_open:
|
||||
self._game_over_modal.draw(surface)
|
||||
return
|
||||
|
||||
surface.fill(self._background_color)
|
||||
|
||||
if self._stack:
|
||||
@@ -132,6 +139,10 @@ class SinglePlayerScene(Scene):
|
||||
TextGenerator.draw("LVL " + level, self._level_label_pos, surface)
|
||||
|
||||
def update(self, elapsed_time: int) -> None:
|
||||
if self._game_over_modal.is_open:
|
||||
self._game_over_modal.update(elapsed_time)
|
||||
return
|
||||
|
||||
if self._current_piece:
|
||||
self._current_piece.update(elapsed_time,\
|
||||
self._well,\
|
||||
@@ -144,8 +155,8 @@ class SinglePlayerScene(Scene):
|
||||
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()
|
||||
SoundManager.stop_theme_music_single()
|
||||
self._game_over_modal.show(False)
|
||||
|
||||
if self._stack:
|
||||
self._stack.update(elapsed_time)
|
||||
@@ -308,9 +319,17 @@ class MultiplayerScene(Scene):
|
||||
self._current_piece_player_one = None
|
||||
self._current_piece_player_two = None
|
||||
|
||||
self._game_over_modal = GameOverModal()
|
||||
self._well_full = False
|
||||
|
||||
self._change_scence = change_scene
|
||||
SoundManager.play_theme_music_multi()
|
||||
|
||||
def draw(self, surface: pygame.Surface) -> None:
|
||||
if self._game_over_modal.is_open:
|
||||
self._game_over_modal.draw(surface)
|
||||
return
|
||||
|
||||
surface.fill(self._background_color)
|
||||
|
||||
# stacks
|
||||
@@ -352,6 +371,10 @@ class MultiplayerScene(Scene):
|
||||
TextGenerator.draw("NEXT", self._next_label_player_one_pos, surface)
|
||||
|
||||
def update(self, elapsed_time: int) -> None:
|
||||
if self._game_over_modal.is_open:
|
||||
self._game_over_modal.update(elapsed_time)
|
||||
return
|
||||
|
||||
self._update_piece_player_one(elapsed_time)
|
||||
self._update_piece_player_two()
|
||||
|
||||
@@ -364,8 +387,10 @@ class MultiplayerScene(Scene):
|
||||
if opponent_stats is not None:
|
||||
self._score_player_two = opponent_stats.score
|
||||
self._total_lines_player_two = opponent_stats.lines
|
||||
if opponent_stats.is_well_full:
|
||||
SoundManager.stop_theme_music_multi()
|
||||
self._game_over_modal.show(True)
|
||||
|
||||
# SEND TO SERVER
|
||||
if self._current_piece_player_one is not None:
|
||||
MultiplayerService.send_piece(PieceDto(self._current_piece_player_one._points,\
|
||||
self._current_piece_player_one._center,\
|
||||
@@ -382,7 +407,7 @@ class MultiplayerScene(Scene):
|
||||
],
|
||||
)
|
||||
)
|
||||
MultiplayerService.send_stats(StatsDto(self._score_player_one, self._stack_player_one.total_lines, False))
|
||||
MultiplayerService.send_stats(StatsDto(self._score_player_one, self._stack_player_one.total_lines, self._well_full))
|
||||
|
||||
def _update_piece_player_one(self, elapsed_time: int) -> None:
|
||||
if self._current_piece_player_one is not None:
|
||||
@@ -397,10 +422,10 @@ class MultiplayerScene(Scene):
|
||||
self._next_piece_player_one = PieceGenerator.get_piece(self._next_piece_player_one_pos)
|
||||
|
||||
# TODO create game over scene
|
||||
if self._stack_player_one and self._current_piece_player_one.collide(self._stack_player_one):
|
||||
pygame.quit()
|
||||
MultiplayerService.quit()
|
||||
sys.exit()
|
||||
if self._stack_player_one and self._current_piece_player_one.collide(self._stack_player_one):
|
||||
self._well_full = True
|
||||
SoundManager.stop_theme_music_multi()
|
||||
self._game_over_modal.show(False)
|
||||
|
||||
def _update_piece_player_two(self) -> None:
|
||||
if self._current_piece_player_two is not None:
|
||||
|
||||
@@ -46,26 +46,43 @@ class SoundManager:
|
||||
@classmethod
|
||||
def init(cls) -> None:
|
||||
pygame.mixer.init()
|
||||
cls._theme_music_ch = pygame.mixer.Channel(0)
|
||||
cls._option_change_sfx_ch = pygame.mixer.Channel(1)
|
||||
cls._piece_rotate_sfx_ch = pygame.mixer.Channel(2)
|
||||
cls._piece_set_sfx_ch = pygame.mixer.Channel(3)
|
||||
cls._line_complete_sfx_ch = pygame.mixer.Channel(4)
|
||||
cls._four_lines_complete_sfx_ch = pygame.mixer.Channel(5)
|
||||
cls._level_up_sfx_ch = pygame.mixer.Channel(6)
|
||||
cls._theme_music_single_ch = pygame.mixer.Channel(0)
|
||||
cls._theme_music_multi_ch = pygame.mixer.Channel(1)
|
||||
cls._option_change_sfx_ch = pygame.mixer.Channel(2)
|
||||
cls._piece_rotate_sfx_ch = pygame.mixer.Channel(3)
|
||||
cls._piece_set_sfx_ch = pygame.mixer.Channel(4)
|
||||
cls._line_complete_sfx_ch = pygame.mixer.Channel(5)
|
||||
cls._four_lines_complete_sfx_ch = pygame.mixer.Channel(6)
|
||||
cls._level_up_sfx_ch = pygame.mixer.Channel(7)
|
||||
|
||||
cls._theme_music = pygame.mixer.Sound(ConfigurationManager.get("sound", "theme-music"))
|
||||
cls._theme_music_single = pygame.mixer.Sound(ConfigurationManager.get("sound", "theme-music-single"))
|
||||
cls._theme_music_multi = pygame.mixer.Sound(ConfigurationManager.get("sound", "theme-music-multi"))
|
||||
cls._option_change_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "option-change"))
|
||||
cls._piece_rotate_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "piece-rotate"))
|
||||
cls._piece_set_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "piece-set"))
|
||||
cls._line_complete_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "line-complete"))
|
||||
cls._four_lines_complete_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "four-lines-complete"))
|
||||
cls._level_up_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "level-up"))
|
||||
cls._game_over_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "game-over"))
|
||||
cls._you_win_sfx = pygame.mixer.Sound(ConfigurationManager.get("sound", "you-win"))
|
||||
|
||||
@classmethod
|
||||
def play_theme_music(cls) -> None:
|
||||
cls._theme_music_ch.set_volume(0.7)
|
||||
cls._theme_music_ch.play(cls._theme_music, -1)
|
||||
def play_theme_music_single(cls) -> None:
|
||||
cls._theme_music_single_ch.set_volume(0.7)
|
||||
cls._theme_music_single_ch.play(cls._theme_music_single, -1)
|
||||
|
||||
@classmethod
|
||||
def stop_theme_music_single(cls) -> None:
|
||||
cls._theme_music_single_ch.stop()
|
||||
|
||||
@classmethod
|
||||
def play_theme_music_multi(cls) -> None:
|
||||
cls._theme_music_multi_ch.set_volume(0.7)
|
||||
cls._theme_music_multi_ch.play(cls._theme_music_multi, -1)
|
||||
|
||||
@classmethod
|
||||
def stop_theme_music_multi(cls) -> None:
|
||||
cls._theme_music_multi_ch.stop()
|
||||
|
||||
@classmethod
|
||||
def play_option_change_sfx(cls) -> None:
|
||||
@@ -93,6 +110,16 @@ class SoundManager:
|
||||
def play_level_up_sfx(cls) -> None:
|
||||
cls._level_up_sfx_ch.play(cls._level_up_sfx)
|
||||
|
||||
@classmethod
|
||||
def play_game_over_sfx(cls) -> None:
|
||||
cls._game_over_sfx.set_volume(0.7)
|
||||
cls._game_over_sfx.play()
|
||||
|
||||
@classmethod
|
||||
def play_you_win_sfx(cls) -> None:
|
||||
cls._you_win_sfx.set_volume(0.7)
|
||||
cls._you_win_sfx.play()
|
||||
|
||||
"""
|
||||
TODO description
|
||||
"""
|
||||
@@ -152,6 +179,7 @@ class TextGenerator:
|
||||
cls._characters[":"] = (2 * glyph_size[0], 11 * glyph_size[1])
|
||||
cls._characters["_"] = (3 * glyph_size[0], 5 * glyph_size[1])
|
||||
cls._characters["."] = (2 * glyph_size[0], 1 * glyph_size[1])
|
||||
cls._characters["!"] = (1 * glyph_size[0], 0 * glyph_size[1])
|
||||
|
||||
@classmethod
|
||||
def draw(cls, text: str, position: Tuple, surface: pygame.Surface) -> None:
|
||||
|
||||
Reference in New Issue
Block a user