diff --git a/Gruntfile.js b/Gruntfile.js index aa7983bf8..3ea7d3116 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -109,6 +109,7 @@ module.exports = function (grunt) { 'src/tween/Tween.js', 'src/tween/Easing.js', 'src/time/Time.js', + 'src/time/Timer.js', 'src/animation/AnimationManager.js', 'src/animation/Animation.js', 'src/animation/Frame.js', diff --git a/README.md b/README.md index 770328e18..0805c3fd3 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ Version 1.1.3 - in build * New: Added Group.sort. You can now sort the Group based on any given numeric property (x, y, health), finally you can do depth-sorting :) Example created to show. * New: Enhanced renderTexture so it can accept a Phaser.Group object and improved documentation and examples. * New: Device.littleEndian boolean added. Only safe to use if the browser supports TypedArrays (which IE9 doesn't, but nearly all others do) +* New: You can now call game.sound.play() and simply pass it a key. The sound will play if the audio system is unlocked and optionally destroy itself on complete. +* New: Mouse.capture is a boolean. If set to true then DOM mouse events will have event.preventDefault() applied, if false they will propogate fully. * Fixed: Lots of fixes to the TypeScript definitions file (many thanks gltovar) * Fixed: Tilemap commands use specified layer when one given (thanks Izzimach) @@ -79,7 +81,7 @@ Version 1.1.3 - in build * Updated: Tided up the Graphics object (thanks BorisKozo) * Updated: If running in Canvas mode and you have a render function it will save the context and reset the transform before running your render function. * Updated: Sprite will now check the exists property of the Group it is in, if the Group.exists = false the Sprite won't update. -* Updated: Lots of documentation tweaks across various files such as Pointer and Color. +* Updated: Lots of documentation tweaks across various files such as Pointer, Sound and Color. * Updated: If you specify 'null' as a Group parent it will now revert to using the World as the parent (before only 'undefined' worked) * Updated: Skip preupdate/update for PIXI hierarchies in which an ancestor doesn't exist (thanks cocoademon) diff --git a/build/config.php b/build/config.php index 14bf6dc8c..07d864a97 100644 --- a/build/config.php +++ b/build/config.php @@ -1,150 +1,159 @@ - - - - + if (!isset($path)) + { + $path = '..'; + } - - - - + echo << - - - + + + + - - - - + + + + - - - - - - - - - - - - - - - - + + + + - + + + + - - + + + + + + + + + + + + + + + + - - - - - - - - - + - - + + - - + + + + + + + + + - - + + - - - - - - - - - - - - - + + - - - - - - - - + + - - - - - - - - - - + + + + + + + + + + + + + - - - - + + + + + + + + - - - + + + + + + + + + + - - - + + + + - + + + - - - + + + - + - - - - - + + + - - - + + - - + + + + + - - + + + - - + + - - - + + - - - - - + + + + + + + + + + + + - + +EOL; +?> diff --git a/examples/_site/view_full.html b/examples/_site/view_full.html index 6edcb1d68..1d9c1418e 100644 --- a/examples/_site/view_full.html +++ b/examples/_site/view_full.html @@ -118,6 +118,7 @@ + diff --git a/examples/_site/view_lite.html b/examples/_site/view_lite.html index e5d124374..d24dc465d 100644 --- a/examples/_site/view_lite.html +++ b/examples/_site/view_lite.html @@ -117,6 +117,7 @@ + diff --git a/src/PixiPatch.js b/src/PixiPatch.js index ec31a3008..5f831c03f 100644 --- a/src/PixiPatch.js +++ b/src/PixiPatch.js @@ -26,7 +26,7 @@ PIXI.CanvasRenderer.prototype.render = function(stage) // if(this.view.style.backgroundColor!=stage.backgroundColorString && !this.transparent)this.view.style.backgroundColor = stage.backgroundColorString; this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.clearRect(0, 0, this.width, this.height) + // this.context.clearRect(0, 0, this.width, this.height) this.renderDisplayObject(stage); // Remove frame updates diff --git a/src/input/Mouse.js b/src/input/Mouse.js index 6ed205bb7..a9ff38456 100644 --- a/src/input/Mouse.js +++ b/src/input/Mouse.js @@ -42,6 +42,11 @@ Phaser.Mouse = function (game) { */ this.mouseUpCallback = null; + /** + * @property {boolean} capture - If true the DOM mouse events will have event.preventDefault applied to them, if false they will propogate fully. + */ + this.capture = true; + /** * @property {number} button- The type of click, either: Phaser.Mouse.NO_BUTTON, Phaser.Mouse.LEFT_BUTTON, Phaser.Mouse.MIDDLE_BUTTON or Phaser.Mouse.RIGHT_BUTTON. * @default @@ -165,7 +170,10 @@ Phaser.Mouse.prototype = { this.event = event; - event.preventDefault(); + if (this.capture) + { + event.preventDefault(); + } this.button = event.which; @@ -194,7 +202,10 @@ Phaser.Mouse.prototype = { this.event = event; - event.preventDefault(); + if (this.capture) + { + event.preventDefault(); + } if (this.mouseMoveCallback) { @@ -221,7 +232,10 @@ Phaser.Mouse.prototype = { this.event = event; - event.preventDefault(); + if (this.capture) + { + event.preventDefault(); + } this.button = Phaser.Mouse.NO_BUTTON; diff --git a/src/sound/Sound.js b/src/sound/Sound.js index 32193c095..d6ed09469 100644 --- a/src/sound/Sound.js +++ b/src/sound/Sound.js @@ -17,7 +17,7 @@ */ Phaser.Sound = function (game, key, volume, loop) { - volume = volume || 1; + if (typeof volume == 'undefined') { volume = 1; } if (typeof loop == 'undefined') { loop = false; } /** @@ -416,18 +416,19 @@ Phaser.Sound.prototype = { * @method Phaser.Sound#play * @param {string} [marker=''] - If you want to play a marker then give the key here, otherwise leave blank to play the full sound. * @param {number} [position=0] - The starting position to play the sound from - this is ignored if you provide a marker. - * @param {number} [volume=1] - Volume of the sound you want to play. + * @param {number} [volume=1] - Volume of the sound you want to play. If none is given it will use the volume given to the Sound when it was created (which defaults to 1 if none was specified). * @param {boolean} [loop=false] - Loop when it finished playing? * @param {boolean} [forceRestart=true] - If the sound is already playing you can set forceRestart to restart it from the beginning. - * @return {Sound} The playing sound object. + * @return {Phaser.Sound} This sound instance. */ play: function (marker, position, volume, loop, forceRestart) { marker = marker || ''; position = position || 0; - volume = volume || 1; - if (typeof loop == 'undefined') { loop = false; } - if (typeof forceRestart == 'undefined') { forceRestart = true; } + + if (typeof volume === 'undefined') { volume = this._volume; } + if (typeof loop === 'undefined') { loop = false; } + if (typeof forceRestart === 'undefined') { forceRestart = true; } // console.log(this.name + ' play ' + marker + ' position ' + position + ' volume ' + volume + ' loop ' + loop, 'force', forceRestart); diff --git a/src/sound/SoundManager.js b/src/sound/SoundManager.js index bedc15ec0..f17544ce4 100644 --- a/src/sound/SoundManager.js +++ b/src/sound/SoundManager.js @@ -324,11 +324,12 @@ Phaser.SoundManager.prototype = { * @param {string} key - Asset key for the sound. * @param {number} [volume=1] - Default value for the volume. * @param {boolean} [loop=false] - Whether or not the sound will loop. + * @return {Phaser.Sound} The new sound instance. */ add: function (key, volume, loop) { - volume = volume || 1; - if (typeof loop == 'undefined') { loop = false; } + if (typeof volume === 'undefined') { volume = 1; } + if (typeof loop === 'undefined') { loop = false; } var sound = new Phaser.Sound(this.game, key, volume, loop); @@ -336,6 +337,27 @@ Phaser.SoundManager.prototype = { return sound; + }, + + /** + * Adds a new Sound into the SoundManager and starts it playing. + * @method Phaser.SoundManager#play + * @param {string} key - Asset key for the sound. + * @param {number} [volume=1] - Default value for the volume. + * @param {boolean} [loop=false] - Whether or not the sound will loop. + * @param {boolean} [destroyOnComplete=false] - If true the Sound will destroy itself once it has finished playing, or is stopped. + * @return {Phaser.Sound} The new sound instance. + */ + play: function (key, volume, loop, destroyOnComplete) { + + if (typeof destroyOnComplete == 'undefined') { destroyOnComplete = false; } + + var sound = this.add(key, volume, loop); + + sound.play(); + + return sound; + } }; diff --git a/src/system/StageScaleMode.js b/src/system/StageScaleMode.js index 117168417..d4a5ee842 100644 --- a/src/system/StageScaleMode.js +++ b/src/system/StageScaleMode.js @@ -117,7 +117,6 @@ Phaser.StageScaleMode = function (game, width, height) { * @default */ this.maxIterations = 5; - /** * @property {PIXI.Sprite} orientationSprite - The Sprite that is optionally displayed if the browser enters an unsupported orientation. @@ -145,6 +144,11 @@ Phaser.StageScaleMode = function (game, width, height) { */ this.leaveIncorrectOrientation = new Phaser.Signal(); + /** + * @property {Phaser.Signal} hasResized - The event that is dispatched when the game scale changes. + */ + this.hasResized = new Phaser.Signal(); + if (window['orientation']) { this.orientation = window['orientation']; @@ -163,9 +167,22 @@ Phaser.StageScaleMode = function (game, width, height) { /** * @property {Phaser.Point} scaleFactor - The scale factor based on the game dimensions vs. the scaled dimensions. + * @readonly */ this.scaleFactor = new Phaser.Point(1, 1); + /** + * @property {Phaser.Point} scaleFactorInversed - The inversed scale factor. The displayed dimensions divided by the game dimensions. + * @readonly + */ + this.scaleFactorInversed = new Phaser.Point(1, 1); + + /** + * @property {Phaser.Point} margin - If the game canvas is seto to align by adjusting the margin, the margin calculation values are stored in this Point. + * @readonly + */ + this.margin = new Phaser.Point(0, 0); + /** * @property {number} aspectRatio - Aspect ratio. * @default @@ -471,14 +488,9 @@ Phaser.StageScaleMode.prototype = { */ refresh: function () { - var _this = this; - // We can't do anything about the status bars in iPads, web apps or desktops if (this.game.device.iPad == false && this.game.device.webApp == false && this.game.device.desktop == false) { - // document.documentElement['style'].minHeight = '2000px'; - // this._startHeight = window.innerHeight; - if (this.game.device.android && this.game.device.chrome == false) { window.scrollTo(0, 1); @@ -492,9 +504,13 @@ Phaser.StageScaleMode.prototype = { if (this._check == null && this.maxIterations > 0) { this._iterations = this.maxIterations; + + var _this = this; + this._check = window.setInterval(function () { return _this.setScreenSize(); }, 10); + this.setScreenSize(); } @@ -588,10 +604,12 @@ Phaser.StageScaleMode.prototype = { { if (this.width < window.innerWidth && this.incorrectOrientation == false) { - this.game.canvas.style.marginLeft = Math.round((window.innerWidth - this.width) / 2) + 'px'; + this.margin.x = Math.round((window.innerWidth - this.width) / 2); + this.game.canvas.style.marginLeft = this.margin.x + 'px'; } else { + this.margin.x = 0; this.game.canvas.style.marginLeft = '0px'; } } @@ -600,10 +618,12 @@ Phaser.StageScaleMode.prototype = { { if (this.height < window.innerHeight && this.incorrectOrientation == false) { - this.game.canvas.style.marginTop = Math.round((window.innerHeight - this.height) / 2) + 'px'; + this.margin.y = Math.round((window.innerHeight - this.height) / 2); + this.game.canvas.style.marginTop = this.margin.y + 'px'; } else { + this.margin.y = 0; this.game.canvas.style.marginTop = '0px'; } } @@ -615,6 +635,11 @@ Phaser.StageScaleMode.prototype = { this.scaleFactor.x = this.game.width / this.width; this.scaleFactor.y = this.game.height / this.height; + this.scaleFactorInversed.x = this.width / this.game.width; + this.scaleFactorInversed.y = this.height / this.game.height; + + this.hasResized.dispatch(this.width, this.height); + this.checkOrientationState(); }, diff --git a/src/time/Time.js b/src/time/Time.js index 04e11f91d..a587542a1 100644 --- a/src/time/Time.js +++ b/src/time/Time.js @@ -146,7 +146,7 @@ Phaser.Time = function (game) { this.game.onResume.add(this.gameResumed, this); /** - * Description. + * Internal value used to recover from the game pause state. * @property {boolean} _justResumed * @default */ @@ -156,15 +156,6 @@ Phaser.Time = function (game) { Phaser.Time.prototype = { - /** - * The number of seconds that have elapsed since the game was started. - * @method Phaser.Time#totalElapsedSeconds - * @return {number} - */ - totalElapsedSeconds: function() { - return (this.now - this._started) * 0.001; - }, - /** * Updates the game clock and calculate the fps. This is called automatically by Phaser.Game. * @method Phaser.Time#update @@ -241,6 +232,15 @@ Phaser.Time.prototype = { }, + /** + * The number of seconds that have elapsed since the game was started. + * @method Phaser.Time#totalElapsedSeconds + * @return {number} + */ + totalElapsedSeconds: function() { + return (this.now - this._started) * 0.001; + }, + /** * How long has passed since the given time. * @method Phaser.Time#elapsedSince diff --git a/src/time/Timer.js b/src/time/Timer.js new file mode 100644 index 000000000..2709f878c --- /dev/null +++ b/src/time/Timer.js @@ -0,0 +1,117 @@ +/** +* @author Richard Davey +* @copyright 2013 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Timer constructor. +* +* @class Phaser.Timer +* @classdesc A Timer +* @constructor +* @param {Phaser.Game} game A reference to the currently running game. +*/ +Phaser.Timer = function (game) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + /** + * The time at which this Timer instance started. + * @property {number} _started + * @private + * @default + */ + this._started = 0; + + /** + * The time (in ms) that the last second counter ticked over. + * @property {number} _timeLastSecond + * @private + * @default + */ + this._timeLastSecond = 0; + + this.running = false; + + this.events = []; + + this.onEvent = new Phaser.Signal(); + + // Need to add custom FPS rate, for now we'll just use seconds + +} + +Phaser.Timer.prototype = { + + // delay could be from now, when the timer is created, or relative to an already running timer + + // add: function (delay, callback, callbackContext) { + add: function (delay) { + + this.events.push({ + delay: delay, + dispatched: false, + args: Array.prototype.splice.call(arguments, 1) + }); + + // this.events.push({ + // delay: delay, + // dispatched: false, + // callback: callback, + // callbackContext: callbackContext, + // args: Array.prototype.splice.call(arguments, 3) + // }); + + }, + + start: function() { + + this._started = this.game.time.now; + this.running = true; + + // sort the events based on delay here, also don't run unless events is populated + // add ability to auto-stop once all events are done + // add support for maximum duration + // add support for delay before starting + // add signals? + + }, + + stop: function() { + + this.running = false; + this.events.length = 0; + + }, + + update: function() { + + // TODO: Game Paused support + + if (this.running) + { + var seconds = this.seconds(); + + for (var i = 0, len = this.events.length; i < len; i++) + { + if (this.events[i].dispatched == false && seconds >= this.events[i].delay) + { + this.events[i].dispatched = true; + // this.events[i].callback.apply(this.events[i].callbackContext, this.events[i].args); + this.onEvent.dispatch.apply(this, this.events[i].args); + // ought to slice it now + } + } + } + + }, + + seconds: function() { + return (this.game.time.now - this._started) * 0.001; + } + +} \ No newline at end of file