added new better music, added ambient music

This commit is contained in:
Faraphel 2023-03-09 23:15:19 +01:00
parent b7933faed6
commit 0578ff41c2
36 changed files with 131 additions and 42 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

12
assets/sound/README.md Normal file
View file

@ -0,0 +1,12 @@
Les effets sonores suivants ont été téléchargé sur le site freesound.org.
Source individuelles :
- placed.wav : https://freesound.org/people/Kayyy/sounds/61015/
- touched.wav : https://freesound.org/people/derplayer/sounds/587196/
- missed.wav : https://freesound.org/people/ComputerHotline/sounds/407060/
- sunken.wav : https://freesound.org/people/Iwiploppenisse/sounds/156031/
- victory.wav : https://freesound.org/people/Sheyvan/sounds/470083/
- defeat.wav : https://freesound.org/people/Unlistenable/sounds/391536/
- menu.wav : https://freesound.org/people/levelclearer/sounds/424271/
- sea.wav : https://freesound.org/people/Pfannkuchn/sounds/360630/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

@ -1,15 +0,0 @@
from .type import Sound
from .abc import MediaGroup
from source.path import path_sound
path = path_sound / "game"
class Game(MediaGroup):
touched = Sound(path / "touched.wav")
sunken_ally = Sound(path / "sunken_ally.wav")
won = Sound(path / "won.wav")
missed = Sound(path / "missed.wav")
sunken_enemy = Sound(path / "sunken_enemy.wav")
loose = Sound(path / "loose.wav")

View file

@ -0,0 +1,10 @@
from .abc import MediaGroup
from source.path import path_sound
from .type import Sound
path = path_sound / "ambient"
class SoundAmbient(MediaGroup):
menu = Sound(path / "menu.wav")
sea = Sound(path / "sea.wav")

View file

@ -0,0 +1,14 @@
from .type import Sound
from .abc import MediaGroup
from source.path import path_sound
path = path_sound / "effect"
class SoundEffect(MediaGroup):
placed = Sound(path / "placed.wav")
touched = Sound(path / "touched.wav")
missed = Sound(path / "missed.wav")
sunken = Sound(path / "sunken.wav")
victory = Sound(path / "victory.wav")
defeat = Sound(path / "defeat.wav")

View file

@ -1 +1,2 @@
from .Game import Game from .SoundEffect import SoundEffect
from .SoundAmbient import SoundAmbient

View file

@ -24,3 +24,7 @@ class MediaGroup(ABC):
@classmethod @classmethod
def set_volume(cls, value: float): def set_volume(cls, value: float):
cls.player.volume = value cls.player.volume = value
@classmethod
def stop(cls):
cls.player.next_source()

View file

@ -20,13 +20,20 @@ class Media(ABC):
cls.loaded_media[path] = media cls.loaded_media[path] = media
# modifie la fonction pour jouer le son en utilisant le player # modifie la fonction pour jouer le son en utilisant le player
def _play(): def _play(loop: bool = False):
owner.player.delete() # arrête la musique en cours s'il y en a une et vide la queue owner.player.next_source() # passe à la prochaine musique
owner.player.queue(media) # ajoute la musique à la queue owner.player.queue(media) # ajoute la musique à la queue
owner.player.play() # joue la musique owner.player.play() # joue la musique
owner.player.on_eos = (lambda: _play(loop=True)) if loop else (lambda: "pass")
media.play = _play media.play = _play
def _play_safe(*args, **kwargs):
if owner.player.source is media: return
media.play(*args, **kwargs) # NOQA
media.play_safe = _play_safe
return media return media
@abstractmethod @abstractmethod

View file

@ -37,6 +37,7 @@ class Game(BaseGame):
PacketBoatPlaced().send_connection(connection) PacketBoatPlaced().send_connection(connection)
self.grid_ally.add_listener("on_all_boats_placed", board_ally_ready) self.grid_ally.add_listener("on_all_boats_placed", board_ally_ready)
self.grid_ally.add_listener("on_boat_placed", lambda *_: media.SoundEffect.placed.play())
def board_enemy_bomb(widget, cell: Point2D): def board_enemy_bomb(widget, cell: Point2D):
if not (self.boat_ready_ally and self.boat_ready_enemy): return if not (self.boat_ready_ally and self.boat_ready_enemy): return
@ -121,6 +122,8 @@ class Game(BaseGame):
self.save_cooldown: Optional[datetime] = None self.save_cooldown: Optional[datetime] = None
media.SoundAmbient.sea.play_safe()
self._refresh_turn_text() self._refresh_turn_text()
self._refresh_score_text() self._refresh_score_text()
@ -294,10 +297,10 @@ class Game(BaseGame):
# joue la musique associée à ce mouvement # joue la musique associée à ce mouvement
match bomb_state: match bomb_state:
case BombState.NOTHING: media.Game.touched.play() case BombState.NOTHING: media.SoundEffect.missed.play()
case BombState.TOUCHED: media.Game.missed.play() case BombState.TOUCHED: media.SoundEffect.touched.play()
case BombState.SUNKEN: media.Game.sunken_ally.play() case BombState.SUNKEN: media.SoundEffect.sunken.play()
case BombState.WON: media.Game.loose.play() case BombState.WON: media.SoundEffect.defeat.play()
# envoie le résultat à l'autre joueur # envoie le résultat à l'autre joueur
PacketBombState(position=packet.position, bomb_state=bomb_state).send_connection(self.connection) PacketBombState(position=packet.position, bomb_state=bomb_state).send_connection(self.connection)
@ -327,10 +330,10 @@ class Game(BaseGame):
# joue la musique associée à ce mouvement # joue la musique associée à ce mouvement
match packet.bomb_state: match packet.bomb_state:
case BombState.NOTHING: media.Game.missed.play() case BombState.NOTHING: media.SoundEffect.missed.play()
case BombState.TOUCHED: media.Game.touched.play() case BombState.TOUCHED: media.SoundEffect.touched.play()
case BombState.SUNKEN: media.Game.sunken_enemy.play() case BombState.SUNKEN: media.SoundEffect.sunken.play()
case BombState.WON: media.Game.won.play() case BombState.WON: media.SoundEffect.victory.play()
if packet.bomb_state is BombState.WON: if packet.bomb_state is BombState.WON:
# si cette bombe a touché le dernier bateau, alors l'on a gagné # si cette bombe a touché le dernier bateau, alors l'on a gagné

View file

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from source.gui import widget, texture from source.gui import widget, texture, media
from source.gui.position import vw_full, vw_center, vh_center, right, px, vw, vh, vh_full from source.gui.position import vw_full, vw_center, vh_center, right, px, vw, vh, vh_full
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
@ -46,3 +46,5 @@ class GameError(Scene):
from source.gui.scene import MainMenu from source.gui.scene import MainMenu
self.back.add_listener("on_click_release", lambda *_: self.window.set_scene(MainMenu)) self.back.add_listener("on_click_release", lambda *_: self.window.set_scene(MainMenu))
media.SoundAmbient.menu.play_safe(loop=True)

View file

@ -1,7 +1,7 @@
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from source.gui import widget, texture from source.gui import widget, texture, media
from source.gui.position import vw_full, vw, vh, right, px, vw_center, vh_center, vh_full from source.gui.position import vw_full, vw, vh, right, px, vw_center, vh_center, vh_full
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.network import Host from source.network import Host
@ -64,6 +64,8 @@ class GameLoad(Scene):
self.accept.add_listener("on_click_release", lambda *_: self.response(value=True)) self.accept.add_listener("on_click_release", lambda *_: self.response(value=True))
media.SoundAmbient.menu.play_safe(loop=True)
def response(self, value: bool): def response(self, value: bool):
self.thread_host.accept_load = value self.thread_host.accept_load = value
self.window.remove_scene(self) self.window.remove_scene(self)

View file

@ -1,7 +1,7 @@
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from source.gui import widget, texture from source.gui import widget, texture, media
from source.gui.position import vw_full, vh, vw, vh_full from source.gui.position import vw_full, vh, vw, vh_full
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.utils import path_ctime_str from source.utils import path_ctime_str
@ -37,3 +37,5 @@ class GameWaitLoad(Scene):
multiline=True, multiline=True,
font_size=28, font_size=28,
) )
media.SoundAmbient.menu.play_safe(loop=True)

View file

@ -2,7 +2,7 @@ import json
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from source.gui import widget, texture from source.gui import widget, texture, media
from source.gui.position import vw, vh, vw_center from source.gui.position import vw, vh, vw_center
from source.gui.scene.abc import BaseGame from source.gui.scene.abc import BaseGame
@ -68,6 +68,8 @@ class HistoryGame(BaseGame):
) )
self._refresh_move_text() self._refresh_move_text()
media.SoundAmbient.menu.play_safe(loop=True)
def _refresh_move_text(self): def _refresh_move_text(self):
self.text_move.text = f"{self.move_number} / {len(self.history)}" self.text_move.text = f"{self.move_number} / {len(self.history)}"
self._refresh_score_text() self._refresh_score_text()

View file

@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
from source.gui.position import vw, vh, top, vh_full, vw_full from source.gui.position import vw, vh, top, vh_full, vw_full
from source.path import path_history from source.path import path_history
from source.gui import widget, texture from source.gui import widget, texture, media
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.utils import path_ctime_str from source.utils import path_ctime_str
@ -112,3 +112,5 @@ class HistoryMenu(Scene):
"on_click_release", "on_click_release",
lambda *_: self.window.set_scene(self.__class__, page=page+1) lambda *_: self.window.set_scene(self.__class__, page=page+1)
) )
media.SoundAmbient.menu.play_safe(loop=True)

View file

@ -2,7 +2,7 @@ from typing import TYPE_CHECKING
from source.gui.position import vw_full, vh_full, vw, vh from source.gui.position import vw_full, vh_full, vw, vh
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.gui import widget, scene, texture from source.gui import widget, scene, texture, media
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
@ -79,3 +79,5 @@ class MainMenu(Scene):
) )
self.settings.add_listener("on_click_release", lambda *_: self.window.add_scene(scene.Settings)) self.settings.add_listener("on_click_release", lambda *_: self.window.add_scene(scene.Settings))
media.SoundAmbient.menu.play_safe(loop=True)

View file

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from source.gui import widget, texture, regex from source.gui import widget, texture, regex, media
from source.gui.position import vw, vh, right, px, vw_full, vh_full from source.gui.position import vw, vh, right, px, vw_full, vh_full
from source.gui.scene import RoomHost from source.gui.scene import RoomHost
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
@ -256,6 +256,8 @@ class RoomCreate(Scene):
self.start.add_listener("on_click_release", lambda *_: self.confirm()) self.start.add_listener("on_click_release", lambda *_: self.confirm())
media.SoundAmbient.menu.play_safe(loop=True)
def confirm(self): def confirm(self):
if not self.valid: return # si tous les formulaires ne sont pas correctement remplis, ignore if not self.valid: return # si tous les formulaires ne sont pas correctement remplis, ignore

View file

@ -5,7 +5,7 @@ import requests
from source import network from source import network
from source.gui.position import vw, vh, vh_full, vw_full from source.gui.position import vw, vh, vh_full, vw_full
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.gui import widget, texture from source.gui import widget, texture, media
from source.utils.thread import in_pyglet_context, StoppableThread from source.utils.thread import in_pyglet_context, StoppableThread
if TYPE_CHECKING: if TYPE_CHECKING:
@ -72,6 +72,8 @@ class RoomHost(Scene):
self.thread_ip = StoppableThread(target=self._refresh_ip) # NOQA self.thread_ip = StoppableThread(target=self._refresh_ip) # NOQA
self.thread_ip.start() self.thread_ip.start()
media.SoundAmbient.menu.play_safe(loop=True)
def _refresh_ip(self): def _refresh_ip(self):
while True: while True:
try: try:

View file

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Optional
from source import network from source import network
from source.gui.position import vw, vh, vw_full, vh_full from source.gui.position import vw, vh, vw_full, vh_full
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.gui import widget, texture, regex from source.gui import widget, texture, regex, media
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
@ -92,6 +92,8 @@ class RoomJoin(Scene):
self.thread: Optional[network.Client] = None self.thread: Optional[network.Client] = None
media.SoundAmbient.menu.play_safe(loop=True)
def button_connect(self, widget, *_): def button_connect(self, widget, *_):
if not self.valid: return # si tous les formulaires ne sont pas correctement remplis, ignore if not self.valid: return # si tous les formulaires ne sont pas correctement remplis, ignore

View file

@ -1,9 +1,6 @@
import itertools
from math import inf from math import inf
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import pyglet.app
from source.gui import widget, texture, media from source.gui import widget, texture, media
from source.gui.position import vw_full, vh_full, vw, vh from source.gui.position import vw_full, vh_full, vw, vh
from source.gui.scene.abc.Popup import Popup from source.gui.scene.abc.Popup import Popup
@ -142,7 +139,7 @@ class Settings(Popup):
font_size=20, font_size=20,
) )
# Volume # Volume Effet Sonore
self.volume_sfx = self.add_widget( self.volume_sfx = self.add_widget(
widget.Scroller, widget.Scroller,
@ -151,14 +148,14 @@ class Settings(Popup):
style=texture.Scroller.Style1, style=texture.Scroller.Style1,
from_=0, from_=0,
value=media.Game.get_volume(), value=media.SoundEffect.get_volume(),
to=1, to=1,
text_transform=lambda value: f"{round(value * 100)}%" text_transform=lambda value: f"{round(value * 100)}%"
) )
def change_volume_sfx(widget): def change_volume_sfx(widget):
media.Game.set_volume(widget.value) media.SoundEffect.set_volume(widget.value)
self.volume_sfx.add_listener( self.volume_sfx.add_listener(
"on_value_change", "on_value_change",
@ -173,3 +170,35 @@ class Settings(Popup):
text="Effets Sonore", text="Effets Sonore",
font_size=20, font_size=20,
) )
# Volume Ambient
self.volume_ambient = self.add_widget(
widget.Scroller,
x=5 * vw, y=76 * vh, width=20 * vw, height=10 * vh,
style=texture.Scroller.Style1,
from_=0,
value=media.SoundAmbient.get_volume(),
to=1,
text_transform=lambda value: f"{round(value * 100)}%"
)
def change_volume_ambient(widget):
media.SoundAmbient.set_volume(widget.value)
self.volume_ambient.add_listener(
"on_value_change",
change_volume_ambient
)
self.add_widget(
widget.Text,
x=27 * vw, y=79 * vh,
text="Musique Ambiante",
font_size=20,
)

View file

@ -238,6 +238,8 @@ class GameGrid(BoxWidget):
else: # if the boat have been placed else: # if the boat have been placed
self.boats_length.pop(0) # remove the boat from the list of boat to place self.boats_length.pop(0) # remove the boat from the list of boat to place
self.trigger_event("on_boat_placed")
if len(self.boats_length) == 0: if len(self.boats_length) == 0:
self.trigger_event("on_all_boats_placed") self.trigger_event("on_all_boats_placed")

View file

@ -4,7 +4,7 @@ from source.gui.better_pyglet import Sprite, Label
from source.gui.texture.abc import Style from source.gui.texture.abc import Style
from source.gui.widget.abc import BoxWidget from source.gui.widget.abc import BoxWidget
from source.type import Distance from source.type import Distance
from source.utils import dict_filter_prefix from source.utils import dict_filter_prefix, in_bbox
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
@ -126,3 +126,7 @@ class Scroller(BoxWidget):
def on_resize(self, width: int, height: int): def on_resize(self, width: int, height: int):
self._refresh() self._refresh()
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
if in_bbox((x, y), self.bbox):
self._refresh_cursor(x - self.x)