phantomcastle: add background music

This commit is contained in:
Dmitry Belyaev 2024-04-06 22:50:23 +03:00
parent ee2c47dc2f
commit a985199441
6 changed files with 56 additions and 2 deletions

BIN
assets/bg.ogg Normal file

Binary file not shown.

View File

@ -1,11 +1,11 @@
assets_files = assets/bg1k.png assets/brick.png assets/coin.png assets/ghost.png assets/win.png assets_files = assets/bg1k.png assets/brick.png assets/coin.png assets/ghost.png assets/win.png assets/bg.ogg
all: build/web.zip all: build/web.zip
assets: assets:
mkdir assets mkdir assets
assets/%.png: assets $(../../assets/*.png) assets/%: assets $(../../assets/*)
cp ../../$@ assets/ cp ../../$@ assets/
build/web: Makefile main.py $(assets_files) build/web: Makefile main.py $(assets_files)

View File

@ -12,6 +12,15 @@ import pygame
from coords import Coords from coords import Coords
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class SurfaceWithRect(NamedTuple): class SurfaceWithRect(NamedTuple):
surface: pygame.Surface surface: pygame.Surface
rect: pygame.Rect rect: pygame.Rect

View File

@ -8,6 +8,7 @@ from game.hero import Hero
from game.wall import Walls from game.wall import Walls
from game.coins import Coins from game.coins import Coins
from game.endlevelmenu import EndLevelMenu from game.endlevelmenu import EndLevelMenu
from sound import BackgroundSound
class Scene(DrawableGameObject, EventHandler): class Scene(DrawableGameObject, EventHandler):
@ -60,6 +61,8 @@ class Scene(DrawableGameObject, EventHandler):
self.exit_rect = self.get_exit_rect() self.exit_rect = self.get_exit_rect()
self.fps = fps self.fps = fps
self.sound = BackgroundSound(self.assets["bg.ogg"])
def get_exit_rect(self) -> pygame.Rect: def get_exit_rect(self) -> pygame.Rect:
# находим клетку в которой будет выход с карты # находим клетку в которой будет выход с карты
maze_sz = get_maze_sz(self.maze) maze_sz = get_maze_sz(self.maze)
@ -119,11 +122,14 @@ class Scene(DrawableGameObject, EventHandler):
self.handle_exit(event) self.handle_exit(event)
if self.done: if self.done:
return return
if event.type == pygame.KEYDOWN and event.key == pygame.K_m:
self.sound.toggle_mute()
self.hero.handle_event(event) self.hero.handle_event(event)
self.check_level_completed() self.check_level_completed()
self.end.handle_event(event) self.end.handle_event(event)
async def event_loop(self): async def event_loop(self):
self.sound.play()
clock = pygame.time.Clock() clock = pygame.time.Clock()
while not self.done: while not self.done:
for event in pygame.event.get(): for event in pygame.event.get():

View File

@ -6,6 +6,7 @@
После прохождения уровня можно начать новый (кнопкой N) или выйти из игры. После прохождения уровня можно начать новый (кнопкой N) или выйти из игры.
Также можно управлять мышкой, перетаскивая героя (зажав ЛКМ) и кликая на надпись, Также можно управлять мышкой, перетаскивая героя (зажав ЛКМ) и кликая на надпись,
для начала новой игры. для начала новой игры.
Музыку можно заглушить (или вернуть), нажав на кнопку M.
Это универсальная версия. Подходит для сборки в виде WASM (для браузера) игры, Это универсальная версия. Подходит для сборки в виде WASM (для браузера) игры,
с помощью pygbag и для запуска напрямую. с помощью pygbag и для запуска напрямую.
@ -61,6 +62,7 @@ async def main():
"brick.png", "brick.png",
"win.png", "win.png",
"coin.png", "coin.png",
"bg.ogg",
] ]
with get_assets_direct(required_assets) as assets: with get_assets_direct(required_assets) as assets:
await game(assets) await game(assets)

View File

@ -0,0 +1,37 @@
import pygame
from common import SingletonMeta
class BackgroundSound(pygame.mixer.Sound, metaclass=SingletonMeta):
def __init__(self, filename):
super().__init__(filename)
self.set_volume(0.5)
self._muted = False
self._played = False
def play(self):
if not self._played:
super().play(loops=-1)
self._played = True
def mute(self):
self._muted = True
self.set_volume(0)
def unmute(self):
self._muted = False
self.set_volume(0.5)
@property
def muted(self):
return self._muted
@muted.setter
def muted(self, value):
if value:
self.mute()
else:
self.unmute()
def toggle_mute(self):
self.muted = not self.muted