/** * Minigame base class for the Spaceship! game. * * Copyright (c) 2008, 2009 Peter Parente under the terms of the BSD license. * http://creativecommons.org/licenses/BSD/ */ dojo.provide('spaceship.minigame.MiniGame'); dojo.require('dijit._Widget'); dojo.require('dijit._Templated'); dojo.require('spaceship.utils.Timer'); dojo.require('spaceship.preferences.PreferencesModel'); dojo.declare('spaceship.minigame.MiniGame', [dijit._Widget, dijit._Templated], { // user preferences prefs: spaceship.preferences.PreferencesModel, // configuration for the minigame based on level only config: null, // audio manager instance set by the minigame manager audio: null, // topic to broadcast on a win set by the minigame manager win_topic: '', // topic to broadcast on a win set by the minigame manager lose_topic: '', // path to CSS to load for this widget; throwback to dojo 0.4 for minigames templateCSSPath: '', constructor: function() { this._audioTok = null; this._audioDefs = {}; this._origVolume = 1.0; }, /** * Stops observing audio callbacks. */ uninitialize: function() { if(this._audioTok) { this.audio.removeObserver(this._audioTok); this._audioTok = null; } this._audioDefs = null; // restore original volume this.audio.setPropertyNow('volume', this.prefs.speechVolume.value, spaceship.sounds.MINIGAME_CHANNEL); }, /** * Returns a deferred response when a sound or utterance finishes * completely or because of an interruption. */ _onAudioNotice: function(audio, response) { var def = this._audioDefs[response.name]; if(def) { if(response.action.search('started') == 0) { def.before.callback(true); } else { delete this._audioDefs[response.name]; def.after.callback(true); } } }, /** * Loads the stylesheet for the minigame if it needs one. */ postMixInProperties: function() { // register for audio notifications immediately var cb = dojo.hitch(this, '_onAudioNotice'); this._audioTok = this.audio.addObserver(cb, spaceship.sounds.MINIGAME_CHANNEL, ['started-say', 'started-play', 'finished-play', 'finished-say', 'error']); if(this.templateCSSPath) { var head = dojo.doc.getElementsByTagName("head")[0]; var cssNode = document.createElement('link'); cssNode.type = 'text/css'; cssNode.rel = 'stylesheet'; cssNode.href = this.templateCSSPath; head.appendChild(cssNode); } }, /** * Helper method picks one random element from an array. * * @param arr An array * @return Random element from the array */ pickRandom: function(arr) { if(!arr.length) throw new Error('empty array'); var i = Math.floor(Math.random()*arr.length); return arr[i]; }, /** * Helper method picks N random elements from an array, allowing dupes. * * @param arr An array * @param n Integer number of elements to pick, defaults to 1 if undefined * @return Array of random elements */ pickRandomN: function(arr, n) { if(!arr.length) throw new Error('empty array'); n = n || 1; var rv = []; for(var i=0; i