/** * @module Kart Kingdom * @namespace springroll.pbskids * @requires Core */ (function() { // Include classes var EventDispatcher = include('springroll.EventDispatcher'); /** * The wrapper for talking to the Kart Kingdom Minigame API. * @class KartKingdom * @constructor * @param {Object} config The configuration * @param {String} config.gameId GUID for your minigame provided by your PBS KIDS content manager * @param {String} config.elementId A string value of the ID of your game's containing element; * presumably a div element which wraps your games canvas element. * @param {Object} [config.options] A configuration object which allows developers to configure * the notification bubble's position and animation timing. * @param {String} [config.options.dock] "TR", "TL", "BL", "BR" * @param {Boolean} [config.options.enable_notifications] * @param {int} [config.options.hide_notification_delay] * @param {int} [config.options.fade_notification_duration] * @param {int} [config.options.slide_notification_duration] */ var KartKingdom = function(config) { EventDispatcher.call(this); /** * Reference to the container instance * @property {Bellhop} container */ this.container = null; /** * The configuration * @property {Object} config */ this.config = config; /** * If this API is enabled * @property {Boolean} enabled * @readOnly * @default false */ this.enabled = false; }; // Reference to the prototype var p = EventDispatcher.extend(KartKingdom); //-------------------- // PUBLIC METHODS //-------------------- /** * Initialize the API * @method init * @param {Bellhop} container The container bellhop instance * @param {Function} done When we're done */ p.init = function(container, done) { this.container = container; this.enabled = container.supported; if (!this.enabled) { return done(); } // Setup event handlers for the bellhop events container.on('kk-ready', _onMinigameReady.bind(this)) .on('kk-level-open', _onLevelOpen.bind(this)) .on('kk-level-closed', _onLevelClosed.bind(this)) .on('kk-level-reset', _onLevelReset.bind(this)) .on('kk-resources-earned', _onResourcesEarned.bind(this)) .on('kk-resources-complete', _onResourcesComplete.bind(this)) .on('kk-init-done', done) .send('kk-init', this.config); // Initialize the kart kingdom minigame }; /** * Called by the producer mini-game whenever the player has accomplished something * in the minigame in which they should receive a reward for the virtual world. * Upon obtaining a reward, a notification will slide-down over the game in the * top-right corner. This notification fades away after 2 seconds. * @method event * @param {String} guid is the guid string, e.g. "ccc006dc-012e-49d0-8b32-35d70df206e9", * for the event/task/item which the user has completed/performed/found which should earn * them a reward in/for the virtual world. To generate events for your mini-game and receive * the guids for those events please contact your PBS KIDS content manager. */ p.event = function(guid) { if (!this.enabled || this.destroyed) return; this.container.send('kk-event', guid); }; /** * Checks if a player is in possession of the requested powerup. Returns false or the integer * quantity of how many of the requested powerup the player possesses. * @method hasPowerUp * @param {String} type the name of the powerup to check, e.g. "rabbit". * @param {Function} callback Payload is a either an Integer or boolean false. <br/> *Integer* -- the current amount of the powerup which * the user has. Return 0 if unlocked but depleted (or not yet acquired). <br/> *Boolean* -- **false**, * if the powerup has not been unlocked by the player. */ p.hasPowerUp = function(type, callback) { if (!this.enabled || this.destroyed) return; this.container.fetch('kk-has-power-up', function(e) { callback(e.data); }, type, true); }; /** * Consumes the requested powerup in the quantities listed for each in the **powerupsObject** object. * Upon validating that the user has all of the powerups in the required amounts, the api will then * make an ajax request to the virtual world to remove (consume) the powerups. The user has successfully * consumed the powerups **ONLY** when the request to the virtual world returns a *200 OK* response; upon * receiving this response the **onSuccessCallback** function is called to notify the minigame of the success. * @method usePowerUps * @param {Object} powerupsObject Object which lists the powerups to consume and in what amounts. * The key-value pairs for each item in the object are the powerup's name as the key and the quantity * to consume as the value, e.g. `{ "water" : 3, "rainforest-map" : 1 }`. * @param {Function} onSuccessCallback A callback method to call when the virtual world backend successfully * consumes the powerups for the user and the user is good to continue in the game. * @param {Function} onFailureCallback A callback method to call when the ajax request to the virtual world * to consume the powerups fails or otherwise does not allow the user to consume the requested powerups. */ var requestID = 1; p.usePowerUps = function(powerupsObject, onSuccessCallback, onFailureCallback) { if (!this.enabled || this.destroyed) return; if (!onSuccessCallback || typeof onSuccessCallback !== "function") { if (DEBUG) throw 'Please supply an onSuccessCallback method as the second parameter.'; return; } var self = this; var successEvent = "kk-use-power-ups-success-" + requestID; var failureEvent = "kk-use-power-ups-failure-" + requestID; requestID++; this.container.on(successEvent, function() { onSuccessCallback(); self.container.off(successEvent); }); this.container.on(failureEvent, function() { if (onFailureCallback && typeof onFailureCallback === "function") onFailureCallback(); self.container.off(failureEvent); }); this.container.send('kk-use-power-ups', { "powerupsObject": powerupsObject, "successEvent": successEvent, "failureEvent": failureEvent }); }; /** * Called by the producer mini-game when the player has completed a level/game, lost, or the * game is otherwise over. Upon calling this method 1 of 3 will appear over your minigame: * 1. If the player is not logged in, then they will see a screen with a link to the virtual world and the message, * "You could be earning cool stuff for the new virtual world, Kart Kingdom!" * * 2. If the player is logged in but has never played in the virtual world, then they will see a screen with the message, * "You could be earning cool stuff for the new virtual world, Kart Kingdom! Come play with other kids!" * * 3. If the player is logged in and has played in the virtual world before, then: * * **a.** If they earned any rewards during this game session, then they will see a list of of the new rewards they earned. * * * **b.** If they did not earn any rewards during this game session, then no screen will appear. * @method levelComplete */ p.levelComplete = function() { if (!this.enabled || this.destroyed) return; this.container.send('kk-level-complete'); }; /** * Destroy the API connection * @method destroy */ p.destroy = function() { if (!this.enabled || this.destroyed) return; if (this.container) { this.container.send('kk-destroy'); this.container = null; } this.config = null; EventDispatcher.prototype.destroy.call(this); }; //-------------------- // EVENT HANDLERS //-------------------- /** * Handler when the game is ready * @method _onMinigameReady * @private * @param {Object} event Bellhop event */ var _onMinigameReady = function(event) { /** * Defines the value of a MinigameReady event. This event fires when a minigame * instance has completed instantiation; this includes having validated the environment, * checked if a user is logged in, and checked if the user has access to the virtual world. * If this event is fired prior to adding an eventlistener for it, then the handler * (2nd parameter) passed to the addEventListener() method will be called immediately * upon event binding with a payload similar to the original event payload. * @event ready * @param {Boolean} isLoggedIn value stating if there is a user currently logged into pbskids.org * @param {Boolean} hasPlayedVirtualWorld value stating if the logged in user has accessed the * virtual world before and has granted the virtual world access to their pbskids.org * account. */ this.trigger('ready', event.data.isLoggedIn, event.data.hasPlayedVirtualWorld); }; /** * Handler when the resources are earned * @method _onResourcesEarned * @private * @param {Object} event Bellhop event */ var _onResourcesEarned = function(event) { /** * Defines the value of a ResourcesEarned event. This event is fired when a player * has earned resources/rewards from the virtual world's rewards system. This event * ONLY occurs if a .event() call results in rewards for that player. If a .event() * call is made where the potential reward is a limited resource and the player has * met that limit, then the player will not earn a reward/resource and this event * will not fire. * @event resourcesEarned * @param {Object} resources An object listing the resources earned from the previous * game event. Has the form `{ resourceName : quantityEarned, resourceName2 : quantityEarned2 }`, * e.g. `{ tools : 1 , water : 3 }`. */ this.trigger('resourcesEarned', event.data); }; /** * Handler when the resources are complete * @method _onResourcesComplete * @private * @param {Object} event Bellhop event */ var _onResourcesComplete = function(event) { /** * Defines the value of a ResourceRequestComplete event. This event fires every time a * request to the rewards api has completed and either returned a response with a rewards * payload, no payload, of if the requests somehow failed and could not complete. Ideally, * this event should fire for each .event() call made. The payload for this jQuery event * object has no additional game data. * @event resourcesComplete */ this.trigger('resourcesComplete'); }; /** * Handler for the bellhop event * @method _onLevelOpen * @private * @param {Object} event Bellhop event */ var _onLevelOpen = function(event) { /** * Defines the value of a LevelCompleteOpen event. This event is fired when the .levelcomplete() * method is called and the level complete overlay opens. The payload for this jQuery event * object has no additional game data. * @event levelOpen */ this.trigger('levelOpen'); }; /** * Handler for the bellhop event * @method _onLevelClosed * @private * @param {Object} event Bellhop event */ var _onLevelClosed = function(event) { /** * Defines the value of a LevelCompleteClosed event. This event is fired when the level complete * overlay is closed by the user. The payload for this jQuery event object has no additional * game data. * @event levelClosed */ this.trigger('levelClosed'); }; /** * Handler for the bellhop event * @method _onLevelReset * @private * @param {Object} event Bellhop event */ var _onLevelReset = function(event) { /** * Defines the value of a LevelReset event. This event is fired when the player stats have been * reset and the enabled state of the notification bubble has been reset to it's initial value. * The payload for this jQuery event object has no additional game data. This event occurs, * * after the level complete overlay has been closed by the user and after the LevelCompleteClosed * event has fired, * or * * after the .levelComplete() method is called, the user is logged in with virtual world access, * and the user has NOT earned any resources/rewards for this level. This would result in a level * reset to occur upon calling the .levelComplete() method and bypassing the level complete display. * @event levelReset */ this.trigger('levelReset'); }; // Define namespace namespace('springroll.pbskids').KartKingdom = KartKingdom; }());