changeset 485:d365eb58f3d6

SoundClip can now fire a callback after a sound has completed being played (i.e. the duration of the sound has passed by). I have added an example of this with the scene music. [t:346]
author prock@33b003aa-7bff-0310-803a-e67f0ece8222
date Fri, 30 Apr 2010 15:37:33 +0000
parents e584b0b8b4a2
children 2aaa22475acd
files demos/shooter/scripts/scene.py demos/shooter/scripts/ships/player.py demos/shooter/scripts/soundmanager.py
diffstat 3 files changed, 84 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/demos/shooter/scripts/scene.py	Fri Apr 30 15:33:27 2010 +0000
+++ b/demos/shooter/scripts/scene.py	Fri Apr 30 15:37:33 2010 +0000
@@ -178,10 +178,14 @@
 		self.addObjectToScene(self._player)
 		
 		self._music = self._soundmanager.loadSoundClip("music/waynesmind2.ogg")
+		self._music.callback = self.musicHasFinished
 		self._music.looping = True
 		self._soundmanager.playClip(self._music)
 		
 		self.startCamera()
+
+	def musicHasFinished(self):
+		print self._music.name + " has finished playing.\n"
 		
 	def pause(self, time):
 		self._pausedtime = time
--- a/demos/shooter/scripts/ships/player.py	Fri Apr 30 15:33:27 2010 +0000
+++ b/demos/shooter/scripts/ships/player.py	Fri Apr 30 15:37:33 2010 +0000
@@ -57,6 +57,7 @@
 
 		self._lives = 3		
 		self.init()
+
 		
 	def init(self):
 		self._hitpoints = 2
@@ -111,6 +112,7 @@
 	def destroy(self):
 		if not self._invulnerable and not self._dead:
 			self._instance.act('explode', self._instance.getFacingLocation())
+			self._scene.soundmanager.playClip(self._explodclip)
 			self._dead = True
 			self._invulnerable = True
 			self._lives -= 1		
--- a/demos/shooter/scripts/soundmanager.py	Fri Apr 30 15:33:27 2010 +0000
+++ b/demos/shooter/scripts/soundmanager.py	Fri Apr 30 15:37:33 2010 +0000
@@ -23,6 +23,38 @@
 
 from fife import fife
 
+class Timer(fife.TimeEvent):
+	def __init__(self,manager, delay=0,callback=None,repeat=0):
+		super(Timer,self).__init__(delay)
+		self._is_registered = False
+		self._callback = callback
+		self._manager = manager
+		self.setPeriod(delay)
+		self._repeat = repeat
+		self._executed = 0
+
+	def start(self):
+		if self._is_registered:
+			return
+		self._is_registered = True
+		self._executed = 0
+		self._manager.registerEvent(self)
+
+	def stop(self):
+		if not self._is_registered:
+			return
+		self._is_registered = False
+		self._manager.unregisterEvent(self)
+
+	def updateEvent(self,delta):
+		if callable(self._callback):
+			self._callback()
+			
+		if self._repeat != 0:
+			self._executed += 1
+			if self._executed >= self._repeat:
+				self.stop()
+
 class SoundClip(object):
 	def __init__(self, soundmanager, clipid, soundname, emitter):
 		self._soundmanager = soundmanager
@@ -32,6 +64,9 @@
 		self._fifeemitter.thisown = 0
 		self._gain = 255.0
 		self._looping = False
+		self._callback = None
+		self._duration = 0
+		self._timer = None
 		
 	def _getClipID(self):
 		return self._fifeclipid
@@ -59,18 +94,39 @@
 	def _getName(self):
 		return self._name
 
+	def _getCallback(self):
+		return self._callback
+
+	def _setCallback(self, 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
+
+	timer = property(_getTimer, _setTimer)
 	clipid = property(_getClipID)
 	gain = property(_getGain, _setGain)
 	looping = property(_getLooping, _setLooping)
 	fifeemitter = property(_getFifeEmitter, _setFifeEmitter)
 	name = property(_getName)
+	callback = property(_getCallback, _setCallback)
+	duration = property(_getDuration, _setDuration)
 
 class SoundManager(object):
 	def __init__(self, engine):
 		self._engine = engine
 		
-		self._soundmanager = self._engine.getSoundManager()
-		self._soundmanager.init()
+		self._fifesoundmanager = self._engine.getSoundManager()
+		self._fifesoundmanager.init()
 		
 		self._emitters = []
 		self._loadedclips = {}
@@ -78,39 +134,50 @@
 	def loadSoundClip(self, filename):
 		if not self._loadedclips.has_key(filename):
 			clipid = self._engine.getSoundClipPool().addResourceFromFile(filename)
-			fifeemitter = self._soundmanager.createEmitter()
+			fifeemitter = self._fifesoundmanager.createEmitter()
 			fifeemitter.thisown = 0
 			fifeemitter.setSoundClip(clipid)
+			
+			time = fifeemitter.getDuration()
+				
 			self._loadedclips[filename] = SoundClip(self, clipid, filename, fifeemitter)
+			self._loadedclips[filename].duration = time/2
 			self._emitters.append(fifeemitter)
 		
 		return self._loadedclips[filename]
 		
 	def playClip(self, clip):
 		if clip.fifeemitter:
+			if clip.callback:
+				if clip.timer:
+					clip.timer.stop()
+				clip.timer = Timer(self._engine.getTimeManager(), clip.duration, clip.callback, 1)
+				clip.timer.start()
+				
 			clip.fifeemitter.setGain(clip.gain)
 			clip.fifeemitter.setLooping(clip.looping)
 			clip.fifeemitter.play()	
 		else:
-			self.loadSoundClip(clip.name)
+			clip = self.loadSoundClip(clip.name)
 				
 	def stopClip(self, clip):
 		if clip.fifeemitter:
 			clip.fifeemitter.stop()
 		else:
-			self.loadSoundClip(clip.name)
+			clip = self.loadSoundClip(clip.name)
+			
+		if clip.timer:
+			clip.timer.stop()
 
 	def stopAllSounds(self):
-		for emitter in self._emitters:
-			emitter.stop()
+		for clip in self._loadedclips.values():	
+			self.stopClip(clip)
 			
 	def destroy(self):
-		print "Destroying " + str(len(self._emitters)) + " sound emitters!\n"
-		print "There are " + str(len(self._loadedclips)) + " unique sounds!\n"
+		self.stopAllSounds()
 	
 		for emitter in self._emitters[:]:
-			emitter.stop()
-			self._soundmanager.releaseEmitter(emitter.getID())
+			self._fifesoundmanager.releaseEmitter(emitter.getID())
 			self._emitters.remove(emitter)
 		
 		for clip in self._loadedclips.values():