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