feat: improve game music

This commit is contained in:
2021-07-08 11:23:47 -04:00
parent e607002062
commit f6ac6a68aa
14 changed files with 111 additions and 34 deletions

View File

@@ -4,9 +4,13 @@ window:
title: "Tetri5"
sound:
main-music: "resource/sound/main_music.ogg"
row-completion: "resource/sound/row_completion.wav"
piece-set: "resource/sound/piece_set_3.wav"
theme-music: "resource/sound/theme_music.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"
image:
title-screen: "resource/image/title_screen.png"

Binary file not shown.

BIN
resource/sound/level_up.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -6,6 +6,7 @@ from typing import List, Tuple
from types import FunctionType
from tetri5.util import ConfigurationManager
from tetri5.util import Controller
from tetri5.util import SoundManager
"""
TODO description
@@ -85,7 +86,6 @@ class Piece(Entity):
super().__init__(Piece._get_points(shape, position), color, border_color)
self._inner_border_color = inner_border_color
self._center = self._get_center(shape, position)
self._piece_set_sound = mixer.Channel(2)
self._previous_points = None
self._previous_center = None
@@ -118,6 +118,8 @@ class Piece(Entity):
self.rotate()
if well and self.collide(well) or stack and self.collide(stack):
self.revert()
else:
SoundManager.play_piece_rotate_sfx()
if Controller.key_down(pygame.K_LEFT):
self.move((-self._tile_size, 0))
if well and self.collide(well) or stack and self.collide(stack):
@@ -223,7 +225,7 @@ class Piece(Entity):
if self._current_set_time >= self._set_time:
self._current_set_time = 0
if self._entity_is_below(well) or self._entity_is_below(stack):
self._play_piece_set_sound()
SoundManager.play_piece_set_sfx()
stack.add_piece(self)
clear_current_piece()
else:
@@ -240,10 +242,6 @@ class Piece(Entity):
return mimic_points
def _play_piece_set_sound(self) -> None:
piece_set_sound_file = ConfigurationManager.get("sound", "piece-set")
self._piece_set_sound.play(mixer.Sound(piece_set_sound_file))
def _entity_is_below(self, entity: Entity) -> bool:
mimic_points = self._mimic_move((0, self._tile_size))
return entity and entity._collide(mimic_points)
@@ -275,7 +273,6 @@ class Stack(Entity):
super().__init__([], color, border_color)
self.total_lines = 0
self.lines_completed_last = 0
self.line_completed_sound = mixer.Channel(1)
def update(self, elapsed_time: int) -> None: # TODO remove scene argument
super().update(elapsed_time)
@@ -305,7 +302,11 @@ class Stack(Entity):
if not squares_to_exclude:
return 0
self._play_line_completed_sound()
if len(rows_completed) == 4:
SoundManager.play_four_lines_complete_sfx()
else:
SoundManager.play_line_complete_sfx()
new_points = []
for square in self._points:
if square not in squares_to_exclude:
@@ -314,17 +315,12 @@ class Stack(Entity):
vertex[1] <= row_completed
for row_completed in rows_completed
)
vertex[1] += self._tile_size * distance_to_move
new_points.append(square)
self._points = new_points
return len(rows_completed)
def _play_line_completed_sound(self) -> None:
line_completed_sound_file = ConfigurationManager.get("sound", "row-completion")
self.line_completed_sound.play(mixer.Sound(line_completed_sound_file))
"""
TODO description
"""

View File

@@ -2,21 +2,19 @@ import sys
import pygame
from tetri5.util import ConfigurationManager
from tetri5.util import TextGenerator
from tetri5.util import SoundManager
from tetri5.scene import Scene, TitleScene
# TODO improve game assets https://www.spriters-resource.com/nes/tetris/
# TODO should be a singleton and refactor the whole file?
# TODO create a util that manages sfx
class Game:
_current_scene = None
@classmethod
def change_scene(cls, scene: Scene) -> None:
cls._current_scene = scene
@classmethod
def init(cls) -> None:
pygame.init()
SoundManager.init()
TextGenerator.init(ConfigurationManager.get("image", "font"), (20, 20))
cls._current_scene = TitleScene(Game.change_scene)
@@ -32,7 +30,6 @@ class Game:
pygame.display.set_caption(win_title)
pygame.display.set_icon(pygame.image.load(win_icon))
# gets called from the games main loop
@classmethod
def update(cls) -> None:
# TODO write not initialized exception
@@ -49,12 +46,15 @@ class Game:
@classmethod
def draw(cls) -> None:
# TODO write not initialized exception
if cls._current_scene:
cls._current_scene.draw(cls.screen)
# update display
pygame.display.update()
@classmethod
def change_scene(cls, scene: Scene) -> None:
cls._current_scene = scene

View File

@@ -1,10 +1,10 @@
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.util import SoundManager
from tetri5.entity import Well
from tetri5.entity import Stack
from tetri5.entity import PieceGenerator
@@ -39,7 +39,6 @@ class TitleScene(Scene):
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:
@@ -53,12 +52,18 @@ class TitleScene(Scene):
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):
option_change = False
if Controller.key_pressed(pygame.K_UP) and self._is_multiplayer:
self._cursor_position = self._cursor_position_one
self._is_multiplayer = False
if Controller.key_pressed(pygame.K_DOWN):
option_change = True
if Controller.key_pressed(pygame.K_DOWN) and not self._is_multiplayer:
self._cursor_position = self._cursor_position_two
self._is_multiplayer = True
option_change = True
if option_change:
SoundManager.play_option_change_sfx() # TODO add cool down
self._cursor_blink_time += elapsed_time
if self._cursor_blink_time >= self._cursor_blink_interval:
@@ -66,7 +71,7 @@ class TitleScene(Scene):
self._cursor_off = not self._cursor_off
if Controller.key_pressed(pygame.K_RETURN):
self._change_scence(SinglePlayerScene(self._change_scence))
self._change_scence(SinglePlayerScene(self._change_scence)) # TODO implement multiplayer
"""
TODO
@@ -77,17 +82,14 @@ class SinglePlayerScene(Scene):
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._previous_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
SoundManager.play_theme_music()
def draw(self, surface: pygame.Surface) -> None:
surface.fill(self._background_color)
@@ -132,6 +134,10 @@ class SinglePlayerScene(Scene):
self._stack.update(elapsed_time)
self._score += self._points_table[self._stack.lines_completed_last] * (self._get_level() + 1)
if self._previous_level != self._get_level():
self._previous_level = self._get_level()
SoundManager.play_level_up_sfx()
def _get_level(self) -> int:
lines_per_level = ConfigurationManager.get("engine", "lines-per-level")

View File

@@ -1,6 +1,6 @@
import yaml
import pygame
from typing import KeysView, Tuple
from typing import Tuple
"""
TODO description
@@ -22,6 +22,77 @@ class ConfigurationManager:
else:
return cls._configuration[key]
"""
TODO description
"""
class SoundManager:
# Channels
_theme_music_ch = None
_option_change_sfx_ch = None
_piece_rotate_sfx_ch = None
_piece_set_sfx_ch = None
_line_complete_sfx_ch = None
_four_lines_complete_sfx_ch = None
# Sounds
_theme_music = None
_option_change_sfx = None
_piece_rotate_sfx = None
_piece_set_sfx = None
_line_complete_sfx = None
_four_lines_complete_sfx = None
@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 = pygame.mixer.Sound(ConfigurationManager.get("sound", "theme-music"))
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"))
@classmethod
def play_theme_music(cls) -> None:
cls._theme_music_ch.set_volume(0.7)
cls._theme_music_ch.play(cls._theme_music, -1)
@classmethod
def play_option_change_sfx(cls) -> None:
cls._option_change_sfx_ch.set_volume(0.8)
cls._option_change_sfx_ch.play(cls._option_change_sfx)
@classmethod
def play_piece_rotate_sfx(cls) -> None:
cls._piece_rotate_sfx_ch.set_volume(0.7)
cls._piece_rotate_sfx_ch.play(cls._piece_rotate_sfx)
@classmethod
def play_piece_set_sfx(cls) -> None:
cls._piece_set_sfx_ch.play(cls._piece_set_sfx)
@classmethod
def play_line_complete_sfx(cls) -> None:
cls._line_complete_sfx_ch.play(cls._line_complete_sfx)
@classmethod
def play_four_lines_complete_sfx(cls) -> None:
cls._four_lines_complete_sfx_ch.play(cls._four_lines_complete_sfx)
@classmethod
def play_level_up_sfx(cls) -> None:
cls._level_up_sfx_ch.play(cls._level_up_sfx)
"""
TODO description
"""