Mercurial > fife-parpg
diff engine/python/fife/extensions/soundmanager.py @ 498:5ff83f209333
Added positioning to the soundmanager classes
Made the player ship explosions positional as usage demonstration
author | nihathrael@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Fri, 14 May 2010 16:23:52 +0000 |
parents | ae9f5383f5b1 |
children | 5e6ff32a46fb |
line wrap: on
line diff
--- a/engine/python/fife/extensions/soundmanager.py Wed May 12 22:03:32 2010 +0000 +++ b/engine/python/fife/extensions/soundmanager.py Fri May 14 16:23:52 2010 +0000 @@ -28,13 +28,13 @@ This is a simple implementation of a sound manager that was originaly intended for the shooter demo. It was functional enough that we decided to include it in the FIFE extensions. This is by no means a fully featured -implementation for several reasons. It doesnt limit how many sounds can -play at once or allow the positioning of sounds. It does however provide +implementation for several reasons. It doesnt limit how many sounds can +play at once or allow the positioning of sounds. It does however provide a good starting point for a more advanced version of a sound manager. Usage:: soundmanager = SoundManager(my_fife_engine) - + emitter = soundmanager.createSoundEmitter("path/filename.ogg") emitter.gain = 128 emitter.play() @@ -50,10 +50,10 @@ """ Wraps the L{fife.SoundEmitter} class. - This class wraps an instance of a L{fife.SoundEmitter} class along + This class wraps an instance of a L{fife.SoundEmitter} class along with some information about a sound clip (like gain and if its looping). All instances of SoundEmitter should be created by SoundManager. - + @todo: At some point this class will store positional information and also be responsible for updating the L{fife.SoundEmitter} position. """ @@ -66,62 +66,65 @@ @param soundname: The filename of the sound @type soundname: C{string} @param emitter: A reference to the L{fife.SoundEmitter} associated with this clip - @type emitter: L{fife.SoundEmitter} - + @type emitter: L{fife.SoundEmitter} + """ self._soundmanager = soundmanager self._name = soundname - + #The FIFE SoundEmitter associated with this SoundEmitter. #Note that we do NOT own the emitter. self._fifeemitter = emitter self._fifeemitter.thisown = 0 self._fifeclipid = clipid - + #0 = mute, 255 = normal volume self._gain = 255.0 self._looping = False - + #if you set the callback it will be executed after the sound #has finished playing. self._callback = None - + #length of the sound self._duration = 0 - + self._timer = None - + + self._position = None + self._rolloff = 0 + def play(self): self._soundmanager.playClip(self) - + def stop(self): self._soundmanager.stopClip(self) - + def _getClipID(self): return self._fifeclipid def _getGain(self): return self._gain - + def _setGain(self, gain): """ Sets the volume of the L{SoundEmitter}. - + @param gain: Value should be from 0-255. 0 being mute and 255 being the normal volume of the clip. @type gain: C{int} """ self._gain = float(gain) - + def _getLooping(self): return self._looping - + def _setLooping(self, looping): self._looping = looping - + def _getFifeEmitter(self): return self._fifeemitter - + def _setFifeEmitter(self, emitter): self._fifeemitter = emitter if self._fifeemitter: @@ -134,20 +137,34 @@ return self._callback def _setCallback(self, cb): - self._callback = cb - + self._callback = cb + def _getDuration(self): return self._duration - + def _setDuration(self, millliseconds): self._duration = millliseconds def _getTimer(self): return self._timer - + def _setTimer(self, timer): self._timer = timer + def _setPosition(self, position): + self._position = position + + def _getPosition(self): + return self._position + + def _setRolloff(self, rolloff): + self._rolloff = rolloff + + def _getRolloff(self): + return self._rolloff + + rolloff = property(_getRolloff, _setRolloff) + position = property(_getPosition, _setPosition) timer = property(_getTimer, _setTimer) clipid = property(_getClipID) gain = property(_getGain, _setGain) @@ -161,8 +178,8 @@ """ A simple sound manager class. - This class manages and plays all the sounds of the game. - It creates SoundEmitters and ensures that there is only one + This class manages and plays all the sounds of the game. + It creates SoundEmitters and ensures that there is only one L{fife.SoundEmitter} per unique sound. """ def __init__(self, engine): @@ -170,26 +187,32 @@ @param engine: A reference to the FIFE engine @type engine: L{fife.Engine} """ - + self._engine = engine - + self._fifesoundmanager = self._engine.getSoundManager() self._fifesoundmanager.init() - + + # basic rolloff used for positional sounds + self._rolloff = 1.9 + #A dict of fife emitters self._loadedclips = {} - - def createSoundEmitter(self, filename, forceUnique=False): + + def createSoundEmitter(self, filename, forceUnique=False, position=None): """ Returns a valid SoundEmitter instance. - + @param filename: The relative path and filename of the sound file @type clip: C{string} @param forceUnique: This forces a new L{fife.SoundEmitter} to be created. - This is useful if you want more than one instance of the same sound + This is useful if you want more than one instance of the same sound to be played at the same time. @type forceUnique: C{boolean} - + @param position: The position on the map that the sound emitter + is to be created at. + @type position: L{tuple} + @return: Returns a new L{SoundEmitter} instance. @rtype: L{SoundEmitter} """ @@ -198,7 +221,6 @@ fifeemitter = self._fifesoundmanager.createEmitter() fifeemitter.thisown = 0 fifeemitter.setSoundClip(clipid) - self._loadedclips[filename] = [fifeemitter] clip = SoundEmitter(self, clipid, filename, fifeemitter) clip.duration = fifeemitter.getDuration() @@ -208,30 +230,33 @@ fifeemitter = self._fifesoundmanager.createEmitter() fifeemitter.thisown = 0 fifeemitter.setSoundClip(clipid) - self._loadedclips[filename].append(fifeemitter) + self._loadedclips[filename].append(fifeemitter) else: fifeemitter = self._loadedclips[filename][0] - + clip = SoundEmitter(self, fifeemitter.getID(), filename, fifeemitter) clip.duration = fifeemitter.getDuration() - + + if position is not None: + clip.position = position + clip.rolloff = self.rolloff return clip - + def playClip(self, clip): """ - Plays a sound clip. - + Plays a sound clip. + This function does not use the L{fife.SoundEmitter} - "looping" property to loop a sound. Instead it registers + "looping" property to loop a sound. Instead it registers a new timer and uses the duration of the clip as the timer length. - - If the SoundEmitter is invalid (no fifeemitter) then it attempts + + If the SoundEmitter is invalid (no fifeemitter) then it attempts to load it before playing it. - + @note: This will stop any clips that use the same L{fife.SoundEmitter}. You cannot play the same sound more than once at a time unless you create the SoundEmitter with the forceUnique paramater set to True. - + @param clip: The L{SoundEmitter} to be played @type clip: L{SoundEmitter} """ @@ -240,7 +265,7 @@ if clip.timer: clip.timer.stop() timer = None - + if clip.looping: repeat = 0 def real_callback(c, e, g): @@ -253,7 +278,7 @@ else: repeat = 1 - + clip.timer = fife_timer.Timer(clip.duration, clip.callback, repeat) #clip.timer.start() else: @@ -266,27 +291,31 @@ clip.callback = cbwa(real_callback, clip.fifeemitter, clip.gain) clip.timer = fife_timer.Timer(clip.duration, clip.callback, 0) #clip.timer.start() - - + + clip.fifeemitter.setGain(float(clip.gain)/255.0) + if clip.position is not None: + # Use 1 as z coordinate, no need to specify it + clip.fifeemitter.setPosition(clip.position[0], clip.position[1], 1) + clip.fifeemitter.setRolloff(clip.rolloff) clip.fifeemitter.play() if clip.timer: clip.timer.start() else: clip = self.createSoundEmitter(clip.name) self.playClip(clip) - + def stopClip(self, clip): """ - Stops playing the sound clip. Note that this will stop all clips that + Stops playing the sound clip. Note that this will stop all clips that use the same FIFE emitter. - + @param clip: The SoundEmitter to stop. @type clip: L{SoundEmitter} """ if clip.fifeemitter: clip.fifeemitter.stop() - + if clip.timer: clip.timer.stop() clip.timer = None @@ -295,20 +324,27 @@ for emitterlist in self._loadedclips.values(): for emitter in emitterlist: emitter.stop() - + def destroy(self): """ - Releases all instances of L{fife.SoundEmitter}. - + Releases all instances of L{fife.SoundEmitter}. + @note: This does not free the resources from the FIFE sound clip pool. """ self.stopAllSounds() - + for emitterlist in self._loadedclips.values(): for emitter in emitterlist: self._fifesoundmanager.releaseEmitter(emitter.getID()) emitter = None - + self._loadedclips.clear() + def _getRolloff(self): + return self._rolloff + + def _setRolloff(self, rolloff): + self._rolloff = rolloff + + rolloff = property(_getRolloff, _setRolloff) __all__ = ['SoundEmitter','SoundManager']