changeset 343:94fdb6c782c1

Implement sfx for player and enemies.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 04 Jul 2012 23:41:28 +0200
parents 83c9354ff3ef
children eab591728abf
files pytouhou/game/enemy.py pytouhou/game/game.py pytouhou/game/item.py pytouhou/game/player.py pytouhou/ui/gamerunner.py pytouhou/ui/music.py pytouhou/vm/eclrunner.py
diffstat 7 files changed, 76 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/enemy.py
+++ b/pytouhou/game/enemy.py
@@ -90,6 +90,26 @@ class Enemy(object):
         return [anm for anm in self.aux_anm if anm]
 
 
+    def play_sound(self, index):
+        name = {
+            5: 'power0',
+            6: 'power1',
+            7: 'tan00',
+            8: 'tan01',
+            9: 'tan02',
+            14: 'cat00',
+            16: 'lazer00',
+            17: 'lazer01',
+            18: 'enep01',
+            22: 'tan00', #XXX
+            24: 'tan02', #XXX
+            25: 'kira00',
+            26: 'kira01',
+            27: 'kira02'
+        }[index]
+        self._game.enemy_sfx.play('%s.wav' % name)
+
+
     def set_bullet_attributes(self, type_, anim, sprite_idx_offset,
                               bullets_per_shot, number_of_shots, speed, speed2,
                               launch_angle, angle, flags):
--- a/pytouhou/game/game.py
+++ b/pytouhou/game/game.py
@@ -328,6 +328,7 @@ class Game(object):
                 elif laser.check_grazing((px, py)):
                     player.state.graze += 1 #TODO
                     player.state.score += 500 #TODO
+                    player.play_sound('graze')
                     self.modify_difficulty(+6) #TODO
                     self.new_particle((px, py), 0, .8, 192) #TODO
 
@@ -351,6 +352,7 @@ class Game(object):
                     bullet.grazed = True
                     player.state.graze += 1
                     player.state.score += 500 # found experimentally
+                    player.play_sound('graze')
                     self.modify_difficulty(+6)
                     self.new_particle((px, py), 0, .8, 192) #TODO: find the real size and range.
                     #TODO: display a static particle during one frame at
--- a/pytouhou/game/item.py
+++ b/pytouhou/game/item.py
@@ -80,6 +80,7 @@ class Item(object):
         score = 0
         label = None
         color = 'white'
+        player.play_sound('item00')
 
         if self._type == 0 or self._type == 2: # power or big power
             if old_power < 128:
@@ -134,6 +135,7 @@ class Item(object):
             if player_state.lives < 8:
                 player_state.lives += 1
             self._game.modify_difficulty(+200)
+            player.play_sound('extend')
 
         elif self._type == 6: # star
             score = 500
--- a/pytouhou/game/player.py
+++ b/pytouhou/game/player.py
@@ -97,11 +97,16 @@ class Player(object):
         self.anmrunner.run_frame()
 
 
+    def play_sound(self, name):
+        self._game.player_sfx.play('%s.wav' % name)
+
+
     def collide(self):
         if not self.state.invulnerable_time and not self.death_time and self.state.touchable: # Border Between Life and Death
             self.death_time = self._game.frame
             self._game.new_effect((self.state.x, self.state.y), 17)
             self._game.modify_difficulty(-1600)
+            self.play_sound('pldead00')
             for i in range(16):
                 self._game.new_particle((self.state.x, self.state.y), 2, 4., 256) #TODO: find the real size and range.
 
@@ -122,6 +127,9 @@ class Player(object):
         lasers = self._game.players_lasers
         nb_bullets_max = self._game.nb_bullets_max
 
+        if self.fire_time % 5 == 0:
+            self.play_sound('plst00')
+
         for shot in sht.shots[power]:
             origin = self.orbs[shot.orb - 1] if shot.orb else self.state
 
--- a/pytouhou/ui/gamerunner.py
+++ b/pytouhou/ui/gamerunner.py
@@ -28,7 +28,7 @@ from pyglet.gl import (glMatrixMode, glL
 from pytouhou.utils.helpers import get_logger
 
 from .gamerenderer import GameRenderer
-from .music import MusicPlayer
+from .music import MusicPlayer, SFXPlayer
 
 
 logger = get_logger(__name__)
@@ -70,6 +70,9 @@ class GameRunner(pyglet.window.Window, G
         game.music = MusicPlayer(game.resource_loader, bgms)
         game.music.play(0)
 
+        game.player_sfx = SFXPlayer(game.resource_loader)
+        game.enemy_sfx = SFXPlayer(game.resource_loader)
+
 
     def start(self, width=None, height=None):
         width = width or (self.game.interface.width if self.game else 640)
--- a/pytouhou/ui/music.py
+++ b/pytouhou/ui/music.py
@@ -15,7 +15,7 @@
 
 from os.path import join
 
-from pyglet.media import AudioData, AudioFormat, Player
+from pyglet.media import AudioData, AudioFormat, StaticSource, Player
 from pyglet.media.riff import WaveSource
 
 
@@ -112,3 +112,37 @@ class MusicPlayer(object):
             self.player.queue(bgm)
         self.player.play()
 
+
+class SFXPlayer(object):
+    def __init__(self, loader):
+        self.loader = loader
+        self.sounds = {}
+
+        self.player = Player()
+        self.player.volume = .5
+
+        #'powerup.wav', 'graze.wav', 'timeout.wav', 'extend.wav', 'kira02.wav', 'kira01.wav',
+        #'kira00.wav', 'item00.wav', 'damage00.wav', 'nep00.wav', 'enep01.wav', 'lazer01.wav',
+        #'lazer00.wav', 'cat00.wav', 'gun00.wav', 'select00.wav', 'cancel00.wav', 'ok00.wav',
+        #'tan02.wav', 'tan01.wav', 'tan00.wav', 'power1.wav', 'power0.wav', 'pldead00.wav',
+        #'enep00.wav', 'plst00.wav')}
+
+
+    def __getitem__(self, name):
+        if not name in self.sounds:
+            self.sounds[name] = self.load_sound(name)
+        return self.sounds[name]
+
+
+    def load_sound(self, name):
+        file = self.loader.get_file(name)
+        return StaticSource(WaveSource(name, file))
+
+    def play(self, name):
+        sound = self[name]
+        if self.player.playing:
+            self.player.next()
+        if sound:
+            self.player.queue(sound)
+        self.player.play()
+
--- a/pytouhou/vm/eclrunner.py
+++ b/pytouhou/vm/eclrunner.py
@@ -830,6 +830,11 @@ class ECLRunner(object):
         self._enemy.damageable = bool(damageable & 1)
 
 
+    @instruction(106)
+    def play_sound(self, index):
+        self._enemy.play_sound(index)
+
+
     @instruction(107)
     def set_death_flags(self, death_flags):
         self._enemy.death_flags = death_flags