diff --git a/Phaser/Game.ts b/Phaser/Game.ts
index c2e373ac..e53a1409 100644
--- a/Phaser/Game.ts
+++ b/Phaser/Game.ts
@@ -8,6 +8,7 @@
///
///
///
+///
///
///
///
@@ -208,6 +209,12 @@ module Phaser {
*/
public motion: Motion;
+ /**
+ * Reference to the network class.
+ * @type {Net}
+ */
+ public net: Net;
+
/**
* Reference to the sound manager.
* @type {SoundManager}
@@ -294,6 +301,7 @@ module Phaser {
else
{
this.device = new Device();
+ this.net = new Net(this);
this.motion = new Motion(this);
this.math = new GameMath(this);
this.stage = new Stage(this, parent, width, height);
diff --git a/Phaser/Phaser.csproj b/Phaser/Phaser.csproj
index 9c479ee7..d3187e44 100644
--- a/Phaser/Phaser.csproj
+++ b/Phaser/Phaser.csproj
@@ -64,6 +64,10 @@
+
+
+ CSS3Filters.ts
+
Debug.ts
@@ -178,6 +182,10 @@
Motion.ts
+
+
+ Net.ts
+
Body.ts
diff --git a/Phaser/Stage.ts b/Phaser/Stage.ts
index 7b61d44c..1d925d4f 100644
--- a/Phaser/Stage.ts
+++ b/Phaser/Stage.ts
@@ -1,5 +1,6 @@
///
///
+///
///
///
///
@@ -52,6 +53,8 @@ module Phaser {
this.context = this.canvas.getContext('2d');
+ this.css3 = new Phaser.Components.CSS3Filters(this.canvas);
+
this.scaleMode = StageScaleMode.NO_SCALE;
this.scale = new StageScaleMode(this._game, width, height);
@@ -97,6 +100,12 @@ module Phaser {
*/
public orientationScreen;
+ /**
+ * Controls the CSS3 Filters applied to the Stages canvas object.
+ * @type {Phaser.Components.CSS3Filters}
+ */
+ public css3: Phaser.Components.CSS3Filters;
+
/**
* Bound of this stage.
* @type {Rectangle}
diff --git a/Phaser/components/CSS3Filters.ts b/Phaser/components/CSS3Filters.ts
new file mode 100644
index 00000000..235d2ad7
--- /dev/null
+++ b/Phaser/components/CSS3Filters.ts
@@ -0,0 +1,170 @@
+///
+
+/**
+* Phaser - Components - CSS3Filters
+*
+* Allows for easy addition and modification of CSS3 Filters on DOM objects (typically the Game.Stage.canvas).
+*/
+
+module Phaser.Components {
+
+ export class CSS3Filters {
+
+ /**
+ * Creates a new CSS3 Filter component
+ * @param parent The DOM object to apply the filters to.
+ */
+ constructor(parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Reference to the parent DOM object (stage.canvas for example)
+ */
+ public parent;
+
+ private _blur: number = 0;
+ private _grayscale: number = 0;
+ private _sepia: number = 0;
+ private _brightness: number = 0;
+ private _contrast: number = 0;
+ private _hueRotate: number = 0;
+ private _invert: number = 0;
+ private _opacity: number = 0;
+ private _saturate: number = 0;
+
+ private setFilter(local: string, prefix: string, value: number, unit: string) {
+
+ this[local] = value;
+
+ if (this.parent)
+ {
+ this.parent.style['-webkit-filter'] = prefix + '(' + value + unit + ')';
+ }
+
+ }
+
+ /**
+ * Applies a Gaussian blur to the DOM element. The value of ‘radius’ defines the value of the standard deviation to the Gaussian function,
+ * or how many pixels on the screen blend into each other, so a larger value will create more blur.
+ * If no parameter is provided, then a value 0 is used. The parameter is specified as a CSS length, but does not accept percentage values.
+ */
+ public set blur(radius?: number = 0) {
+ this.setFilter('_blur', 'blur', radius, 'px');
+ }
+
+ public get blur(): number {
+ return this._blur;
+ }
+
+ /**
+ * Converts the input image to grayscale. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely grayscale. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public set grayscale(amount?: number = 100) {
+ this.setFilter('_grayscale', 'grayscale', amount, '%');
+ }
+
+ public get grayscale(): number {
+ return this._grayscale;
+ }
+
+ /**
+ * Converts the input image to sepia. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely sepia. A value of 0 leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public set sepia(amount?: number = 100) {
+ this.setFilter('_sepia', 'sepia', amount, '%');
+ }
+
+ public get sepia(): number {
+ return this._sepia;
+ }
+
+ /**
+ * Applies a linear multiplier to input image, making it appear more or less bright.
+ * A value of 0% will create an image that is completely black. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of an amount over 100% are allowed, providing brighter results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public set brightness(amount?: number = 100) {
+ this.setFilter('_brightness', 'brightness', amount, '%');
+ }
+
+ public get brightness(): number {
+ return this._brightness;
+ }
+
+ /**
+ * Adjusts the contrast of the input. A value of 0% will create an image that is completely black.
+ * A value of 100% leaves the input unchanged. Values of amount over 100% are allowed, providing results with less contrast.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public set contrast(amount?: number = 100) {
+ this.setFilter('_contrast', 'contrast', amount, '%');
+ }
+
+ public get contrast(): number {
+ return this._contrast;
+ }
+
+ /**
+ * Applies a hue rotation on the input image. The value of ‘angle’ defines the number of degrees around the color circle
+ * the input samples will be adjusted. A value of 0deg leaves the input unchanged. If the ‘angle’ parameter is missing,
+ * a value of 0deg is used. Maximum value is 360deg.
+ */
+ public set hueRotate(angle?: number = 0) {
+ this.setFilter('_hueRotate', 'hue-rotate', angle, 'deg');
+ }
+
+ public get hueRotate(): number {
+ return this._hueRotate;
+ }
+
+ /**
+ * Inverts the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely inverted. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public set invert(value?: number = 100) {
+ this.setFilter('_invert', 'invert', value, '%');
+ }
+
+ public get invert(): number {
+ return this._invert;
+ }
+
+ /**
+ * Applies transparency to the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely transparent. A value of 100% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. This is equivalent to multiplying the input image samples by amount.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ * This function is similar to the more established opacity property; the difference is that with filters, some browsers provide hardware acceleration for better performance.
+ */
+ public set opacity(value?: number = 100) {
+ this.setFilter('_opacity', 'opacity', value, '%');
+ }
+
+ public get opacity(): number {
+ return this._opacity;
+ }
+
+ /**
+ * Saturates the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely un-saturated. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of amount over 100% are allowed, providing super-saturated results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public set saturate(value?: number = 100) {
+ this.setFilter('_saturate', 'saturate', value, '%');
+ }
+
+ public get saturate(): number {
+ return this._saturate;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/Phaser/components/sprite/Input.ts b/Phaser/components/sprite/Input.ts
index 94bbd9ca..0816a341 100644
--- a/Phaser/components/sprite/Input.ts
+++ b/Phaser/components/sprite/Input.ts
@@ -311,6 +311,7 @@ module Phaser.Components.Sprite {
if (this.enabled == false || this._parent.visible == false)
{
+ this._pointerOutHandler(pointer);
return false;
}
diff --git a/Phaser/gameobjects/DynamicTexture.ts b/Phaser/gameobjects/DynamicTexture.ts
index 579eadcd..2f325e71 100644
--- a/Phaser/gameobjects/DynamicTexture.ts
+++ b/Phaser/gameobjects/DynamicTexture.ts
@@ -34,6 +34,8 @@ module Phaser {
this.canvas.height = height;
this.context = this.canvas.getContext('2d');
+ this.css3 = new Phaser.Components.CSS3Filters(this.canvas);
+
this.bounds = new Rectangle(0, 0, width, height);
}
@@ -59,6 +61,13 @@ module Phaser {
// Input / Output nodes?
+ /**
+ * Controls the CSS3 Filters applied to the textures canvas object.
+ * Only really useful if you attach this canvas to the DOM.
+ * @type {Phaser.Components.CSS3Filters}
+ */
+ public css3: Phaser.Components.CSS3Filters;
+
/**
* Bound of this texture with width and height info.
* @type {Rectangle}
diff --git a/Phaser/net/Net.ts b/Phaser/net/Net.ts
new file mode 100644
index 00000000..e100a5d9
--- /dev/null
+++ b/Phaser/net/Net.ts
@@ -0,0 +1,135 @@
+///
+
+/**
+* Phaser - Net
+*
+*
+*/
+
+module Phaser {
+
+ export class Net {
+
+ /**
+ * Net constructor
+ */
+ constructor(game: Game) {
+
+ this.game = game;
+
+ }
+
+ /**
+ * Local reference to the current Phaser.Game.
+ */
+ public game: Game;
+
+ /**
+ * Compares the given domain name against the hostname of the browser containing the game.
+ * If the domain name is found it returns true.
+ * You can specify a part of a domain, for example 'google' would match 'google.com', 'google.co.uk', etc.
+ * Do not include 'http://' at the start.
+ */
+ public checkDomainName(domain: string): bool {
+ return window.location.hostname.indexOf(domain) !== -1;
+ }
+
+ /**
+ * Updates a value on the Query String and returns it in full.
+ * If the value doesn't already exist it is set.
+ * If the value exists it is replaced with the new value given. If you don't provide a new value it is removed from the query string.
+ * Optionally you can redirect to the new url, or just return it as a string.
+ */
+ public updateQueryString(key: string, value: string, redirect?:bool = false, url?: string = ''):string {
+
+ if (url == '')
+ {
+ url = window.location.href;
+ }
+
+ var output: string = '';
+
+ var re:RegExp = new RegExp("([?|&])" + key + "=.*?(&|#|$)(.*)", "gi");
+
+ if (re.test(url))
+ {
+ if (typeof value !== 'undefined' && value !== null)
+ {
+ output = url.replace(re, '$1' + key + "=" + value + '$2$3');
+ }
+ else
+ {
+ output = url.replace(re, '$1$3').replace(/(&|\?)$/, '');
+ }
+ }
+ else
+ {
+ if (typeof value !== 'undefined' && value !== null)
+ {
+ var separator = url.indexOf('?') !== -1 ? '&' : '?';
+ var hash = url.split('#');
+
+ url = hash[0] + separator + key + '=' + value;
+
+ if (hash[1])
+ {
+ url += '#' + hash[1];
+ }
+
+ output = url;
+ }
+ else
+ {
+ output = url;
+ }
+ }
+
+ if (redirect)
+ {
+ window.location.href = output;
+ }
+ else
+ {
+ return output;
+ }
+
+ }
+
+ /**
+ * Returns the Query String as an object.
+ * If you specify a parameter it will return just the value of that parameter, should it exist.
+ */
+ public getQueryString(parameter?: string = '') {
+
+ var output = {};
+ var keyValues = location.search.substring(1).split('&');
+
+ for (var i in keyValues)
+ {
+ var key = keyValues[i].split('=');
+
+ if (key.length > 1)
+ {
+ if (parameter && parameter == this.decodeURI(key[0]))
+ {
+ return this.decodeURI(key[1]);
+ }
+ else
+ {
+ output[this.decodeURI(key[0])] = this.decodeURI(key[1]);
+ }
+ }
+ }
+
+ return output;
+
+ }
+
+ private decodeURI(value: string): string {
+ return decodeURIComponent(value.replace(/\+/g, " "));
+ }
+
+
+ }
+
+}
diff --git a/Phaser/sound/SoundManager.ts b/Phaser/sound/SoundManager.ts
index 835f5282..2e036234 100644
--- a/Phaser/sound/SoundManager.ts
+++ b/Phaser/sound/SoundManager.ts
@@ -4,7 +4,6 @@
/**
* Phaser - SoundManager
*
-* This is an embroyonic web audio sound management class. There is a lot of work still to do here.
*/
module Phaser {
diff --git a/README.md b/README.md
index 7cba62fe..cb82869d 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,6 @@ TODO:
* Investigate bug re: tilemap collision and animation frames
* Update tests that use arrow keys and include touch/mouse support (FlxControlHandler style)
* Texture Repeat doesn't scroll, because it's part of the camera not the world, need to think about this more
-* Stage CSS3 transforms!!! Color tints, sepia, greyscale, all of those cool things :)
* Add JSON Texture Atlas object support.
* Pointer.getWorldX(camera) needs to take camera scale into consideration
* If stage.clear set to false and game pauses, when it unpauses you still see the pause arrow - resolve this
@@ -56,11 +55,10 @@ TODO:
* Tilemap.render - move layers length to var
* Camera control method (touch/keyboard)
* Tilemap.destroy needs doing
-* Look at the input targetObject - it doesn't seem to get cleared down all the time, maybe just a priority/alpha issue (check vis/alpha?)
* Sprite.transform.bottomRight/Left doesn't seem to take origin into account
-* When you toggle visible of a button that is over, it doesn't disable that 'over' state (should it? probably yes)
* Stage.opaqueBackground = 'rgb()' or null, alpha, blendMode, filters, mask, rotation+XYZ,scaleXYZ,visible
-
+* Stage CSS3 Transforms?
+* Ability to layer another DOM object and have it controlled by the game somehow. Can then do stacked canvas effects.
* Stage lost to mute
@@ -157,6 +155,8 @@ V1.0.0
* SoundManager will now automatically handle iOS touch unlocking.
* Added TilemapLayer.putTileWorldXY to place a tile based on pixel values, and putTile based on tile map coordinates.
* Dropped the StageScaleMode.setScreenSize iterations count from 40 down to 10 and document min body height to 2000px.
+* Added Phaser.Net for browser and network specific functions, currently includes query string parsing and updating methods.
+* Added a new CSS3 Filters component. Apply blur, grayscale, sepia, brightness, contrast, hue rotation, invert, opacity and saturate filters to the games stage.
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index bd659391..e35c5c8c 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -242,6 +242,34 @@
origin 5.ts
+
+
+ blur filter.ts
+
+
+
+
+ brightness filter.ts
+
+
+
+ contrast filter.ts
+
+
+
+ grayscale filter.ts
+
+
+
+ hue rotate filter.ts
+
+
+ sepia filter.ts
+
+
+
+ filter test.ts
+
csv tilemap.ts
diff --git a/Tests/phaser.js b/Tests/phaser.js
index 163996cf..ff65ffdd 100644
--- a/Tests/phaser.js
+++ b/Tests/phaser.js
@@ -1,4 +1,4 @@
-///
+///
/**
* Phaser - Point
*
@@ -2004,6 +2004,7 @@ var Phaser;
this.canvas.width = width;
this.canvas.height = height;
this.context = this.canvas.getContext('2d');
+ this.css3 = new Phaser.Components.CSS3Filters(this.canvas);
this.bounds = new Phaser.Rectangle(0, 0, width, height);
}
DynamicTexture.prototype.getPixel = /**
@@ -3607,6 +3608,7 @@ var Phaser;
*/
function (pointer) {
if(this.enabled == false || this._parent.visible == false) {
+ this._pointerOutHandler(pointer);
return false;
}
if(this.draggable && this._draggedPointerID == pointer.id) {
@@ -9461,6 +9463,97 @@ var Phaser;
})(Phaser || (Phaser = {}));
///
/**
+* Phaser - Net
+*
+*
+*/
+var Phaser;
+(function (Phaser) {
+ var Net = (function () {
+ /**
+ * Net constructor
+ */
+ function Net(game) {
+ this.game = game;
+ }
+ Net.prototype.checkDomainName = /**
+ * Compares the given domain name against the hostname of the browser containing the game.
+ * If the domain name is found it returns true.
+ * You can specify a part of a domain, for example 'google' would match 'google.com', 'google.co.uk', etc.
+ * Do not include 'http://' at the start.
+ */
+ function (domain) {
+ return window.location.hostname.indexOf(domain) !== -1;
+ };
+ Net.prototype.updateQueryString = /**
+ * Updates a value on the Query String and returns it in full.
+ * If the value doesn't already exist it is set.
+ * If the value exists it is replaced with the new value given. If you don't provide a new value it is removed from the query string.
+ * Optionally you can redirect to the new url, or just return it as a string.
+ */
+ function (key, value, redirect, url) {
+ if (typeof redirect === "undefined") { redirect = false; }
+ if (typeof url === "undefined") { url = ''; }
+ if(url == '') {
+ url = window.location.href;
+ }
+ var output = '';
+ var re = new RegExp("([?|&])" + key + "=.*?(&|#|$)(.*)", "gi");
+ if(re.test(url)) {
+ if(typeof value !== 'undefined' && value !== null) {
+ output = url.replace(re, '$1' + key + "=" + value + '$2$3');
+ } else {
+ output = url.replace(re, '$1$3').replace(/(&|\?)$/, '');
+ }
+ } else {
+ if(typeof value !== 'undefined' && value !== null) {
+ var separator = url.indexOf('?') !== -1 ? '&' : '?';
+ var hash = url.split('#');
+ url = hash[0] + separator + key + '=' + value;
+ if(hash[1]) {
+ url += '#' + hash[1];
+ }
+ output = url;
+ } else {
+ output = url;
+ }
+ }
+ if(redirect) {
+ window.location.href = output;
+ } else {
+ return output;
+ }
+ };
+ Net.prototype.getQueryString = /**
+ * Returns the Query String as an object.
+ * If you specify a parameter it will return just the value of that parameter, should it exist.
+ */
+ function (parameter) {
+ if (typeof parameter === "undefined") { parameter = ''; }
+ var output = {
+ };
+ var keyValues = location.search.substring(1).split('&');
+ for(var i in keyValues) {
+ var key = keyValues[i].split('=');
+ if(key.length > 1) {
+ if(parameter && parameter == this.decodeURI(key[0])) {
+ return this.decodeURI(key[1]);
+ } else {
+ output[this.decodeURI(key[0])] = this.decodeURI(key[1]);
+ }
+ }
+ }
+ return output;
+ };
+ Net.prototype.decodeURI = function (value) {
+ return decodeURIComponent(value.replace(/\+/g, " "));
+ };
+ return Net;
+ })();
+ Phaser.Net = Net;
+})(Phaser || (Phaser = {}));
+///
+/**
* Phaser - Cache
*
* A game only has one instance of a Cache and it is used to store all externally loaded assets such
@@ -14349,7 +14442,7 @@ var Phaser;
}
} else {
//console.log('Sound play Audio');
- if(this.game.cache.getSound(this.key).locked) {
+ if(this.game.cache.getSound(this.key) && this.game.cache.getSound(this.key).locked) {
//console.log('tried playing locked sound, pending set, reload started');
this.game.cache.reloadSound(this.key);
this.pendingPlayback = true;
@@ -14362,7 +14455,11 @@ var Phaser;
//console.log('playing', this._sound);
this._sound.currentTime = this.position;
this._sound.muted = this._muted;
- this._sound.volume = this._volume;
+ if(this._muted) {
+ this._sound.volume = 0;
+ } else {
+ this._sound.volume = this._volume;
+ }
this._sound.play();
this.isPlaying = true;
this.startTime = this.game.time.now;
@@ -14503,7 +14600,6 @@ var Phaser;
/**
* Phaser - SoundManager
*
-* This is an embroyonic web audio sound management class. There is a lot of work still to do here.
*/
var Phaser;
(function (Phaser) {
@@ -14612,6 +14708,7 @@ var Phaser;
return this._muted;
},
set: function (value) {
+ console.log('SoundManager mute', value);
if(value) {
if(this._muted) {
return;
@@ -14623,7 +14720,7 @@ var Phaser;
}
// Loop through sounds
for(var i = 0; i < this._sounds.length; i++) {
- if(this._sounds[i]) {
+ if(this._sounds[i].usingAudioTag) {
this._sounds[i].mute = true;
}
}
@@ -14637,7 +14734,7 @@ var Phaser;
}
// Loop through sounds
for(var i = 0; i < this._sounds.length; i++) {
- if(this._sounds[i]) {
+ if(this._sounds[i].usingAudioTag) {
this._sounds[i].mute = false;
}
}
@@ -14761,6 +14858,192 @@ var Phaser;
(function (Phaser) {
Phaser.VERSION = 'Phaser version 1.0.0';
})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ /**
+ * Phaser - Components - CSS3Filters
+ *
+ * Allows for easy addition and modification of CSS3 Filters on DOM objects (typically the Game.Stage.canvas).
+ */
+ (function (Components) {
+ var CSS3Filters = (function () {
+ /**
+ * Creates a new CSS3 Filter component
+ * @param parent The DOM object to apply the filters to.
+ */
+ function CSS3Filters(parent) {
+ this._blur = 0;
+ this._grayscale = 0;
+ this._sepia = 0;
+ this._brightness = 0;
+ this._contrast = 0;
+ this._hueRotate = 0;
+ this._invert = 0;
+ this._opacity = 0;
+ this._saturate = 0;
+ this.parent = parent;
+ }
+ CSS3Filters.prototype.setFilter = function (local, prefix, value, unit) {
+ this[local] = value;
+ if(this.parent) {
+ this.parent.style['-webkit-filter'] = prefix + '(' + value + unit + ')';
+ }
+ };
+ Object.defineProperty(CSS3Filters.prototype, "blur", {
+ get: function () {
+ return this._blur;
+ },
+ set: /**
+ * Applies a Gaussian blur to the DOM element. The value of ‘radius’ defines the value of the standard deviation to the Gaussian function,
+ * or how many pixels on the screen blend into each other, so a larger value will create more blur.
+ * If no parameter is provided, then a value 0 is used. The parameter is specified as a CSS length, but does not accept percentage values.
+ */
+ function (radius) {
+ if (typeof radius === "undefined") { radius = 0; }
+ this.setFilter('_blur', 'blur', radius, 'px');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "grayscale", {
+ get: function () {
+ return this._grayscale;
+ },
+ set: /**
+ * Converts the input image to grayscale. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely grayscale. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_grayscale', 'grayscale', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "sepia", {
+ get: function () {
+ return this._sepia;
+ },
+ set: /**
+ * Converts the input image to sepia. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely sepia. A value of 0 leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_sepia', 'sepia', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "brightness", {
+ get: function () {
+ return this._brightness;
+ },
+ set: /**
+ * Applies a linear multiplier to input image, making it appear more or less bright.
+ * A value of 0% will create an image that is completely black. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of an amount over 100% are allowed, providing brighter results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_brightness', 'brightness', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "contrast", {
+ get: function () {
+ return this._contrast;
+ },
+ set: /**
+ * Adjusts the contrast of the input. A value of 0% will create an image that is completely black.
+ * A value of 100% leaves the input unchanged. Values of amount over 100% are allowed, providing results with less contrast.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_contrast', 'contrast', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "hueRotate", {
+ get: function () {
+ return this._hueRotate;
+ },
+ set: /**
+ * Applies a hue rotation on the input image. The value of ‘angle’ defines the number of degrees around the color circle
+ * the input samples will be adjusted. A value of 0deg leaves the input unchanged. If the ‘angle’ parameter is missing,
+ * a value of 0deg is used. Maximum value is 360deg.
+ */
+ function (angle) {
+ if (typeof angle === "undefined") { angle = 0; }
+ this.setFilter('_hueRotate', 'hue-rotate', angle, 'deg');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "invert", {
+ get: function () {
+ return this._invert;
+ },
+ set: /**
+ * Inverts the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely inverted. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (value) {
+ if (typeof value === "undefined") { value = 100; }
+ this.setFilter('_invert', 'invert', value, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "opacity", {
+ get: function () {
+ return this._opacity;
+ },
+ set: /**
+ * Applies transparency to the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely transparent. A value of 100% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. This is equivalent to multiplying the input image samples by amount.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ * This function is similar to the more established opacity property; the difference is that with filters, some browsers provide hardware acceleration for better performance.
+ */
+ function (value) {
+ if (typeof value === "undefined") { value = 100; }
+ this.setFilter('_opacity', 'opacity', value, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "saturate", {
+ get: function () {
+ return this._saturate;
+ },
+ set: /**
+ * Saturates the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely un-saturated. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of amount over 100% are allowed, providing super-saturated results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (value) {
+ if (typeof value === "undefined") { value = 100; }
+ this.setFilter('_saturate', 'saturate', value, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return CSS3Filters;
+ })();
+ Components.CSS3Filters = CSS3Filters;
+ })(Phaser.Components || (Phaser.Components = {}));
+ var Components = Phaser.Components;
+})(Phaser || (Phaser = {}));
///
/**
* Phaser - StageScaleMode
@@ -14843,6 +15126,11 @@ var Phaser;
* @type {number}
*/
this.height = 0;
+ /**
+ * The maximum number of times it will try to resize the canvas to fill the browser (default is 10)
+ * @type {number}
+ */
+ this.maxIterations = 10;
this._game = game;
this.enterLandscape = new Phaser.Signal();
this.enterPortrait = new Phaser.Signal();
@@ -14994,8 +15282,8 @@ var Phaser;
window.scrollTo(0, 0);
}
}
- if(this._check == null) {
- this._iterations = 10;
+ if(this._check == null && this.maxIterations > 0) {
+ this._iterations = this.maxIterations;
this._check = window.setInterval(function () {
return _this.setScreenSize();
}, 10);
@@ -15348,6 +15636,7 @@ var Phaser;
})(Phaser || (Phaser = {}));
///
///
+///
///
///
///
@@ -15413,6 +15702,7 @@ var Phaser;
event.preventDefault();
};
this.context = this.canvas.getContext('2d');
+ this.css3 = new Phaser.Components.CSS3Filters(this.canvas);
this.scaleMode = Phaser.StageScaleMode.NO_SCALE;
this.scale = new Phaser.StageScaleMode(this._game, width, height);
this.getOffset(this.canvas);
@@ -15453,8 +15743,13 @@ var Phaser;
function () {
this.scale.update();
if(this.clear) {
- // implement dirty rect? could take up more cpu time than it saves. needs benching.
- this.context.clearRect(0, 0, this.width, this.height);
+ // A 'fix' for the horrendous Android stock browser bug: https://code.google.com/p/android/issues/detail?id=39247
+ if(this._game.device.android && this._game.device.chrome == false) {
+ this.context.fillStyle = 'rgb(0,0,0)';
+ this.context.fillRect(0, 0, this.width, this.height);
+ } else {
+ this.context.clearRect(0, 0, this.width, this.height);
+ }
}
if(this._game.paused && this.scale.incorrectOrientation) {
this.orientationScreen.update();
@@ -19618,6 +19913,7 @@ var Phaser;
///
///
///
+///
///
///
///
@@ -19790,6 +20086,7 @@ var Phaser;
}, 13);
} else {
this.device = new Phaser.Device();
+ this.net = new Phaser.Net(this);
this.motion = new Phaser.Motion(this);
this.math = new Phaser.GameMath(this);
this.stage = new Phaser.Stage(this, parent, width, height);
diff --git a/Tests/stage/blur filter.js b/Tests/stage/blur filter.js
new file mode 100644
index 00000000..0fe9b70d
--- /dev/null
+++ b/Tests/stage/blur filter.js
@@ -0,0 +1,26 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+ }
+ function create() {
+ game.world.setSize(1920, 1200);
+ game.add.sprite(0, 0, 'backdrop');
+ // Apply a 4px blur to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.blur = 4;
+ }
+ function update() {
+ if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
+ game.camera.x -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
+ game.camera.x += 4;
+ }
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+})();
diff --git a/Tests/stage/blur filter.ts b/Tests/stage/blur filter.ts
new file mode 100644
index 00000000..6a478d5c
--- /dev/null
+++ b/Tests/stage/blur filter.ts
@@ -0,0 +1,47 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+
+ }
+
+ function create() {
+
+ game.world.setSize(1920, 1200);
+
+ game.add.sprite(0, 0, 'backdrop');
+
+ // Apply a 4px blur to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.blur = 4;
+
+ }
+
+ function update() {
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
+ {
+ game.camera.x -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
+ {
+ game.camera.x += 4;
+ }
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+})();
diff --git a/Tests/stage/brightness filter.js b/Tests/stage/brightness filter.js
new file mode 100644
index 00000000..6ff93d45
--- /dev/null
+++ b/Tests/stage/brightness filter.js
@@ -0,0 +1,26 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+ }
+ function create() {
+ game.world.setSize(1920, 1200);
+ game.add.sprite(0, 0, 'backdrop');
+ // Apply a 150% brightness filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.brightness = 150;
+ }
+ function update() {
+ if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
+ game.camera.x -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
+ game.camera.x += 4;
+ }
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+})();
diff --git a/Tests/stage/brightness filter.ts b/Tests/stage/brightness filter.ts
new file mode 100644
index 00000000..7b8f100b
--- /dev/null
+++ b/Tests/stage/brightness filter.ts
@@ -0,0 +1,47 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+
+ }
+
+ function create() {
+
+ game.world.setSize(1920, 1200);
+
+ game.add.sprite(0, 0, 'backdrop');
+
+ // Apply a 150% brightness filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.brightness = 150;
+
+ }
+
+ function update() {
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
+ {
+ game.camera.x -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
+ {
+ game.camera.x += 4;
+ }
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+})();
diff --git a/Tests/stage/contrast filter.js b/Tests/stage/contrast filter.js
new file mode 100644
index 00000000..11b2fb22
--- /dev/null
+++ b/Tests/stage/contrast filter.js
@@ -0,0 +1,26 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+ }
+ function create() {
+ game.world.setSize(1920, 1200);
+ game.add.sprite(0, 0, 'backdrop');
+ // Apply a 250% contrast filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.contrast = 250;
+ }
+ function update() {
+ if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
+ game.camera.x -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
+ game.camera.x += 4;
+ }
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+})();
diff --git a/Tests/stage/contrast filter.ts b/Tests/stage/contrast filter.ts
new file mode 100644
index 00000000..43e55ec1
--- /dev/null
+++ b/Tests/stage/contrast filter.ts
@@ -0,0 +1,47 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+
+ }
+
+ function create() {
+
+ game.world.setSize(1920, 1200);
+
+ game.add.sprite(0, 0, 'backdrop');
+
+ // Apply a 250% contrast filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.contrast = 250;
+
+ }
+
+ function update() {
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
+ {
+ game.camera.x -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
+ {
+ game.camera.x += 4;
+ }
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+})();
diff --git a/Tests/stage/grayscale filter.js b/Tests/stage/grayscale filter.js
new file mode 100644
index 00000000..0e6ed430
--- /dev/null
+++ b/Tests/stage/grayscale filter.js
@@ -0,0 +1,26 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+ }
+ function create() {
+ game.world.setSize(1920, 1200);
+ game.add.sprite(0, 0, 'backdrop');
+ // Apply a 100% contrast filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.grayscale = 100;
+ }
+ function update() {
+ if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
+ game.camera.x -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
+ game.camera.x += 4;
+ }
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+})();
diff --git a/Tests/stage/grayscale filter.ts b/Tests/stage/grayscale filter.ts
new file mode 100644
index 00000000..2baeb0cd
--- /dev/null
+++ b/Tests/stage/grayscale filter.ts
@@ -0,0 +1,47 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+
+ }
+
+ function create() {
+
+ game.world.setSize(1920, 1200);
+
+ game.add.sprite(0, 0, 'backdrop');
+
+ // Apply a 100% contrast filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.grayscale = 100;
+
+ }
+
+ function update() {
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
+ {
+ game.camera.x -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
+ {
+ game.camera.x += 4;
+ }
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+})();
diff --git a/Tests/stage/hue rotate filter.js b/Tests/stage/hue rotate filter.js
new file mode 100644
index 00000000..e1684de0
--- /dev/null
+++ b/Tests/stage/hue rotate filter.js
@@ -0,0 +1,28 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/large-color-wheel.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+ game.load.start();
+ }
+ var hue = 0;
+ function create() {
+ game.world.setSize(800, 800);
+ game.add.sprite(0, 0, 'backdrop');
+ game.add.sprite(30, 20, 'coke');
+ game.add.sprite(600, 20, 'mushroom');
+ }
+ function update() {
+ // The value is given in degrees, so between 0 and 360, hence the wrapValue call below.
+ hue = game.math.wrapValue(hue, 1, 360);
+ // Apply a hue rotation to the stage
+ game.stage.css3.hueRotate = hue;
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+})();
diff --git a/Tests/stage/hue rotate filter.ts b/Tests/stage/hue rotate filter.ts
new file mode 100644
index 00000000..362c11b2
--- /dev/null
+++ b/Tests/stage/hue rotate filter.ts
@@ -0,0 +1,47 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/large-color-wheel.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+ game.load.start();
+
+ }
+
+ var hue: number = 0;
+
+ function create() {
+
+ game.world.setSize(800, 800);
+
+ game.add.sprite(0, 0, 'backdrop');
+ game.add.sprite(30, 20, 'coke');
+ game.add.sprite(600, 20, 'mushroom');
+
+ }
+
+ function update() {
+
+ // The value is given in degrees, so between 0 and 360, hence the wrapValue call below.
+ hue = game.math.wrapValue(hue, 1, 360);
+
+ // Apply a hue rotation to the stage
+ game.stage.css3.hueRotate = hue;
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+})();
diff --git a/Tests/stage/sepia filter.js b/Tests/stage/sepia filter.js
new file mode 100644
index 00000000..6302640f
--- /dev/null
+++ b/Tests/stage/sepia filter.js
@@ -0,0 +1,26 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+ }
+ function create() {
+ game.world.setSize(1920, 1200);
+ game.add.sprite(0, 0, 'backdrop');
+ // Apply a 100% sepia filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.sepia = 100;
+ }
+ function update() {
+ if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
+ game.camera.x -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
+ game.camera.x += 4;
+ }
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+})();
diff --git a/Tests/stage/sepia filter.ts b/Tests/stage/sepia filter.ts
new file mode 100644
index 00000000..e6fb78a8
--- /dev/null
+++ b/Tests/stage/sepia filter.ts
@@ -0,0 +1,47 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/remember-me.jpg');
+ game.load.start();
+
+ }
+
+ function create() {
+
+ game.world.setSize(1920, 1200);
+
+ game.add.sprite(0, 0, 'backdrop');
+
+ // Apply a 100% sepia filter to the entire game (this value can be tweened, modified in-game, etc)
+ game.stage.css3.sepia = 100;
+
+ }
+
+ function update() {
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
+ {
+ game.camera.x -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
+ {
+ game.camera.x += 4;
+ }
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+})();
diff --git a/Tests/textures/filter test.js b/Tests/textures/filter test.js
new file mode 100644
index 00000000..74f81eb4
--- /dev/null
+++ b/Tests/textures/filter test.js
@@ -0,0 +1,39 @@
+///
+(function () {
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
+ function init() {
+ game.load.image('backdrop', 'assets/pics/large-color-wheel.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+ game.load.start();
+ }
+ var hue = 0;
+ var texture;
+ function create() {
+ game.world.setSize(800, 800);
+ texture = game.add.dynamicTexture(800, 600);
+ var backdrop = game.add.sprite(0, 0, 'backdrop');
+ var cokecan = game.add.sprite(30, 20, 'coke');
+ var mushroom = game.add.sprite(600, 20, 'mushroom');
+ texture.assignCanvasToGameObjects([
+ backdrop,
+ cokecan,
+ mushroom
+ ]);
+ texture.css3.grayscale = 100;
+ }
+ function update() {
+ // The value is given in degrees, so between 0 and 360, hence the wrapValue call below.
+ hue = game.math.wrapValue(hue, 1, 360);
+ // Apply a hue rotation to the stage
+ //game.stage.css3.hueRotate = hue;
+ if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
+ game.camera.y -= 4;
+ } else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
+ game.camera.y += 4;
+ }
+ }
+ function render() {
+ texture.render();
+ }
+})();
diff --git a/Tests/textures/filter test.ts b/Tests/textures/filter test.ts
new file mode 100644
index 00000000..ab1dcdee
--- /dev/null
+++ b/Tests/textures/filter test.ts
@@ -0,0 +1,61 @@
+///
+
+(function () {
+
+ var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
+
+ function init() {
+
+ game.load.image('backdrop', 'assets/pics/large-color-wheel.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+ game.load.start();
+
+ }
+
+ var hue: number = 0;
+ var texture: Phaser.DynamicTexture;
+
+ function create() {
+
+ game.world.setSize(800, 800);
+
+ texture = game.add.dynamicTexture(800, 600);
+
+ var backdrop = game.add.sprite(0, 0, 'backdrop');
+ var cokecan = game.add.sprite(30, 20, 'coke');
+ var mushroom = game.add.sprite(600, 20, 'mushroom');
+
+ texture.assignCanvasToGameObjects([backdrop, cokecan, mushroom]);
+
+ // Rats, filters don't get applied when the canvas is drawn to another canvas. Oh well :)
+ texture.css3.grayscale = 100;
+
+ }
+
+ function update() {
+
+ // The value is given in degrees, so between 0 and 360, hence the wrapValue call below.
+ hue = game.math.wrapValue(hue, 1, 360);
+
+ // Apply a hue rotation to the stage
+ //game.stage.css3.hueRotate = hue;
+
+ if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
+ {
+ game.camera.y -= 4;
+ }
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
+ {
+ game.camera.y += 4;
+ }
+
+ }
+
+ function render() {
+
+ texture.render();
+
+ }
+
+})();
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index 50fea951..33f5318a 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -1,4 +1,4 @@
-/**
+/**
* Phaser - Point
*
* The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
@@ -1325,6 +1325,11 @@ module Phaser {
private _dw;
private _dh;
/**
+ * Controls the CSS3 Filters applied to the textures canvas object.
+ * @type {Phaser.Components.CSS3Filters}
+ */
+ public css3: Components.CSS3Filters;
+ /**
* Bound of this texture with width and height info.
* @type {Rectangle}
*/
@@ -4365,6 +4370,43 @@ module Phaser {
}
}
/**
+* Phaser - Net
+*
+*
+*/
+module Phaser {
+ class Net {
+ /**
+ * Net constructor
+ */
+ constructor(game: Game);
+ /**
+ * Local reference to the current Phaser.Game.
+ */
+ public game: Game;
+ /**
+ * Compares the given domain name against the hostname of the browser containing the game.
+ * If the domain name is found it returns true.
+ * You can specify a part of a domain, for example 'google' would match 'google.com', 'google.co.uk', etc.
+ * Do not include 'http://' at the start.
+ */
+ public checkDomainName(domain: string): bool;
+ /**
+ * Updates a value on the Query String and returns it in full.
+ * If the value doesn't already exist it is set.
+ * If the value exists it is replaced with the new value given. If you don't provide a new value it is removed from the query string.
+ * Optionally you can redirect to the new url, or just return it as a string.
+ */
+ public updateQueryString(key: string, value: string, redirect?: bool, url?: string): string;
+ /**
+ * Returns the Query String as an object.
+ * If you specify a parameter it will return just the value of that parameter, should it exist.
+ */
+ public getQueryString(parameter?: string): {};
+ private decodeURI(value);
+ }
+}
+/**
* Phaser - Cache
*
* A game only has one instance of a Cache and it is used to store all externally loaded assets such
@@ -7063,7 +7105,6 @@ module Phaser {
/**
* Phaser - SoundManager
*
-* This is an embroyonic web audio sound management class. There is a lot of work still to do here.
*/
module Phaser {
class SoundManager {
@@ -7141,6 +7182,92 @@ module Phaser {
var VERSION: string;
}
/**
+* Phaser - Components - CSS3Filters
+*
+* Allows for easy addition and modification of CSS3 Filters on DOM objects (typically the Game.Stage.canvas).
+*/
+module Phaser.Components {
+ class CSS3Filters {
+ /**
+ * Creates a new CSS3 Filter component
+ * @param parent The DOM object to apply the filters to.
+ */
+ constructor(parent);
+ /**
+ * Reference to the parent DOM object (stage.canvas for example)
+ */
+ public parent;
+ private _blur;
+ private _grayscale;
+ private _sepia;
+ private _brightness;
+ private _contrast;
+ private _hueRotate;
+ private _invert;
+ private _opacity;
+ private _saturate;
+ private setFilter(local, prefix, value, unit);
+ /**
+ * Applies a Gaussian blur to the DOM element. The value of ‘radius’ defines the value of the standard deviation to the Gaussian function,
+ * or how many pixels on the screen blend into each other, so a larger value will create more blur.
+ * If no parameter is provided, then a value 0 is used. The parameter is specified as a CSS length, but does not accept percentage values.
+ */
+ public blur : number;
+ /**
+ * Converts the input image to grayscale. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely grayscale. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public grayscale : number;
+ /**
+ * Converts the input image to sepia. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely sepia. A value of 0 leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public sepia : number;
+ /**
+ * Applies a linear multiplier to input image, making it appear more or less bright.
+ * A value of 0% will create an image that is completely black. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of an amount over 100% are allowed, providing brighter results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public brightness : number;
+ /**
+ * Adjusts the contrast of the input. A value of 0% will create an image that is completely black.
+ * A value of 100% leaves the input unchanged. Values of amount over 100% are allowed, providing results with less contrast.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public contrast : number;
+ /**
+ * Applies a hue rotation on the input image. The value of ‘angle’ defines the number of degrees around the color circle
+ * the input samples will be adjusted. A value of 0deg leaves the input unchanged. If the ‘angle’ parameter is missing,
+ * a value of 0deg is used. Maximum value is 360deg.
+ */
+ public hueRotate : number;
+ /**
+ * Inverts the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely inverted. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public invert : number;
+ /**
+ * Applies transparency to the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely transparent. A value of 100% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. This is equivalent to multiplying the input image samples by amount.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ * This function is similar to the more established opacity property; the difference is that with filters, some browsers provide hardware acceleration for better performance.
+ */
+ public opacity : number;
+ /**
+ * Saturates the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely un-saturated. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of amount over 100% are allowed, providing super-saturated results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ public saturate : number;
+ }
+}
+/**
* Phaser - StageScaleMode
*
* This class controls the scaling of your game. On mobile devices it will also remove the URL bar and allow
@@ -7246,6 +7373,11 @@ module Phaser {
*/
public aspectRatio: number;
/**
+ * The maximum number of times it will try to resize the canvas to fill the browser (default is 10)
+ * @type {number}
+ */
+ public maxIterations: number;
+ /**
* The scale factor of the scaled game width
* @type {Vec2}
*/
@@ -7502,6 +7634,11 @@ module Phaser {
*/
public orientationScreen;
/**
+ * Controls the CSS3 Filters applied to the Stages canvas object.
+ * @type {Phaser.Components.CSS3Filters}
+ */
+ public css3: Components.CSS3Filters;
+ /**
* Bound of this stage.
* @type {Rectangle}
*/
@@ -9823,6 +9960,11 @@ module Phaser {
*/
public motion: Motion;
/**
+ * Reference to the network class.
+ * @type {Net}
+ */
+ public net: Net;
+ /**
* Reference to the sound manager.
* @type {SoundManager}
*/
diff --git a/build/phaser.js b/build/phaser.js
index 163996cf..ff65ffdd 100644
--- a/build/phaser.js
+++ b/build/phaser.js
@@ -1,4 +1,4 @@
-///
+///
/**
* Phaser - Point
*
@@ -2004,6 +2004,7 @@ var Phaser;
this.canvas.width = width;
this.canvas.height = height;
this.context = this.canvas.getContext('2d');
+ this.css3 = new Phaser.Components.CSS3Filters(this.canvas);
this.bounds = new Phaser.Rectangle(0, 0, width, height);
}
DynamicTexture.prototype.getPixel = /**
@@ -3607,6 +3608,7 @@ var Phaser;
*/
function (pointer) {
if(this.enabled == false || this._parent.visible == false) {
+ this._pointerOutHandler(pointer);
return false;
}
if(this.draggable && this._draggedPointerID == pointer.id) {
@@ -9461,6 +9463,97 @@ var Phaser;
})(Phaser || (Phaser = {}));
///
/**
+* Phaser - Net
+*
+*
+*/
+var Phaser;
+(function (Phaser) {
+ var Net = (function () {
+ /**
+ * Net constructor
+ */
+ function Net(game) {
+ this.game = game;
+ }
+ Net.prototype.checkDomainName = /**
+ * Compares the given domain name against the hostname of the browser containing the game.
+ * If the domain name is found it returns true.
+ * You can specify a part of a domain, for example 'google' would match 'google.com', 'google.co.uk', etc.
+ * Do not include 'http://' at the start.
+ */
+ function (domain) {
+ return window.location.hostname.indexOf(domain) !== -1;
+ };
+ Net.prototype.updateQueryString = /**
+ * Updates a value on the Query String and returns it in full.
+ * If the value doesn't already exist it is set.
+ * If the value exists it is replaced with the new value given. If you don't provide a new value it is removed from the query string.
+ * Optionally you can redirect to the new url, or just return it as a string.
+ */
+ function (key, value, redirect, url) {
+ if (typeof redirect === "undefined") { redirect = false; }
+ if (typeof url === "undefined") { url = ''; }
+ if(url == '') {
+ url = window.location.href;
+ }
+ var output = '';
+ var re = new RegExp("([?|&])" + key + "=.*?(&|#|$)(.*)", "gi");
+ if(re.test(url)) {
+ if(typeof value !== 'undefined' && value !== null) {
+ output = url.replace(re, '$1' + key + "=" + value + '$2$3');
+ } else {
+ output = url.replace(re, '$1$3').replace(/(&|\?)$/, '');
+ }
+ } else {
+ if(typeof value !== 'undefined' && value !== null) {
+ var separator = url.indexOf('?') !== -1 ? '&' : '?';
+ var hash = url.split('#');
+ url = hash[0] + separator + key + '=' + value;
+ if(hash[1]) {
+ url += '#' + hash[1];
+ }
+ output = url;
+ } else {
+ output = url;
+ }
+ }
+ if(redirect) {
+ window.location.href = output;
+ } else {
+ return output;
+ }
+ };
+ Net.prototype.getQueryString = /**
+ * Returns the Query String as an object.
+ * If you specify a parameter it will return just the value of that parameter, should it exist.
+ */
+ function (parameter) {
+ if (typeof parameter === "undefined") { parameter = ''; }
+ var output = {
+ };
+ var keyValues = location.search.substring(1).split('&');
+ for(var i in keyValues) {
+ var key = keyValues[i].split('=');
+ if(key.length > 1) {
+ if(parameter && parameter == this.decodeURI(key[0])) {
+ return this.decodeURI(key[1]);
+ } else {
+ output[this.decodeURI(key[0])] = this.decodeURI(key[1]);
+ }
+ }
+ }
+ return output;
+ };
+ Net.prototype.decodeURI = function (value) {
+ return decodeURIComponent(value.replace(/\+/g, " "));
+ };
+ return Net;
+ })();
+ Phaser.Net = Net;
+})(Phaser || (Phaser = {}));
+///
+/**
* Phaser - Cache
*
* A game only has one instance of a Cache and it is used to store all externally loaded assets such
@@ -14349,7 +14442,7 @@ var Phaser;
}
} else {
//console.log('Sound play Audio');
- if(this.game.cache.getSound(this.key).locked) {
+ if(this.game.cache.getSound(this.key) && this.game.cache.getSound(this.key).locked) {
//console.log('tried playing locked sound, pending set, reload started');
this.game.cache.reloadSound(this.key);
this.pendingPlayback = true;
@@ -14362,7 +14455,11 @@ var Phaser;
//console.log('playing', this._sound);
this._sound.currentTime = this.position;
this._sound.muted = this._muted;
- this._sound.volume = this._volume;
+ if(this._muted) {
+ this._sound.volume = 0;
+ } else {
+ this._sound.volume = this._volume;
+ }
this._sound.play();
this.isPlaying = true;
this.startTime = this.game.time.now;
@@ -14503,7 +14600,6 @@ var Phaser;
/**
* Phaser - SoundManager
*
-* This is an embroyonic web audio sound management class. There is a lot of work still to do here.
*/
var Phaser;
(function (Phaser) {
@@ -14612,6 +14708,7 @@ var Phaser;
return this._muted;
},
set: function (value) {
+ console.log('SoundManager mute', value);
if(value) {
if(this._muted) {
return;
@@ -14623,7 +14720,7 @@ var Phaser;
}
// Loop through sounds
for(var i = 0; i < this._sounds.length; i++) {
- if(this._sounds[i]) {
+ if(this._sounds[i].usingAudioTag) {
this._sounds[i].mute = true;
}
}
@@ -14637,7 +14734,7 @@ var Phaser;
}
// Loop through sounds
for(var i = 0; i < this._sounds.length; i++) {
- if(this._sounds[i]) {
+ if(this._sounds[i].usingAudioTag) {
this._sounds[i].mute = false;
}
}
@@ -14761,6 +14858,192 @@ var Phaser;
(function (Phaser) {
Phaser.VERSION = 'Phaser version 1.0.0';
})(Phaser || (Phaser = {}));
+var Phaser;
+(function (Phaser) {
+ ///
+ /**
+ * Phaser - Components - CSS3Filters
+ *
+ * Allows for easy addition and modification of CSS3 Filters on DOM objects (typically the Game.Stage.canvas).
+ */
+ (function (Components) {
+ var CSS3Filters = (function () {
+ /**
+ * Creates a new CSS3 Filter component
+ * @param parent The DOM object to apply the filters to.
+ */
+ function CSS3Filters(parent) {
+ this._blur = 0;
+ this._grayscale = 0;
+ this._sepia = 0;
+ this._brightness = 0;
+ this._contrast = 0;
+ this._hueRotate = 0;
+ this._invert = 0;
+ this._opacity = 0;
+ this._saturate = 0;
+ this.parent = parent;
+ }
+ CSS3Filters.prototype.setFilter = function (local, prefix, value, unit) {
+ this[local] = value;
+ if(this.parent) {
+ this.parent.style['-webkit-filter'] = prefix + '(' + value + unit + ')';
+ }
+ };
+ Object.defineProperty(CSS3Filters.prototype, "blur", {
+ get: function () {
+ return this._blur;
+ },
+ set: /**
+ * Applies a Gaussian blur to the DOM element. The value of ‘radius’ defines the value of the standard deviation to the Gaussian function,
+ * or how many pixels on the screen blend into each other, so a larger value will create more blur.
+ * If no parameter is provided, then a value 0 is used. The parameter is specified as a CSS length, but does not accept percentage values.
+ */
+ function (radius) {
+ if (typeof radius === "undefined") { radius = 0; }
+ this.setFilter('_blur', 'blur', radius, 'px');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "grayscale", {
+ get: function () {
+ return this._grayscale;
+ },
+ set: /**
+ * Converts the input image to grayscale. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely grayscale. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_grayscale', 'grayscale', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "sepia", {
+ get: function () {
+ return this._sepia;
+ },
+ set: /**
+ * Converts the input image to sepia. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely sepia. A value of 0 leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_sepia', 'sepia', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "brightness", {
+ get: function () {
+ return this._brightness;
+ },
+ set: /**
+ * Applies a linear multiplier to input image, making it appear more or less bright.
+ * A value of 0% will create an image that is completely black. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of an amount over 100% are allowed, providing brighter results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_brightness', 'brightness', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "contrast", {
+ get: function () {
+ return this._contrast;
+ },
+ set: /**
+ * Adjusts the contrast of the input. A value of 0% will create an image that is completely black.
+ * A value of 100% leaves the input unchanged. Values of amount over 100% are allowed, providing results with less contrast.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (amount) {
+ if (typeof amount === "undefined") { amount = 100; }
+ this.setFilter('_contrast', 'contrast', amount, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "hueRotate", {
+ get: function () {
+ return this._hueRotate;
+ },
+ set: /**
+ * Applies a hue rotation on the input image. The value of ‘angle’ defines the number of degrees around the color circle
+ * the input samples will be adjusted. A value of 0deg leaves the input unchanged. If the ‘angle’ parameter is missing,
+ * a value of 0deg is used. Maximum value is 360deg.
+ */
+ function (angle) {
+ if (typeof angle === "undefined") { angle = 0; }
+ this.setFilter('_hueRotate', 'hue-rotate', angle, 'deg');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "invert", {
+ get: function () {
+ return this._invert;
+ },
+ set: /**
+ * Inverts the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 100% is completely inverted. A value of 0% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (value) {
+ if (typeof value === "undefined") { value = 100; }
+ this.setFilter('_invert', 'invert', value, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "opacity", {
+ get: function () {
+ return this._opacity;
+ },
+ set: /**
+ * Applies transparency to the samples in the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely transparent. A value of 100% leaves the input unchanged.
+ * Values between 0% and 100% are linear multipliers on the effect. This is equivalent to multiplying the input image samples by amount.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ * This function is similar to the more established opacity property; the difference is that with filters, some browsers provide hardware acceleration for better performance.
+ */
+ function (value) {
+ if (typeof value === "undefined") { value = 100; }
+ this.setFilter('_opacity', 'opacity', value, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(CSS3Filters.prototype, "saturate", {
+ get: function () {
+ return this._saturate;
+ },
+ set: /**
+ * Saturates the input image. The value of ‘amount’ defines the proportion of the conversion.
+ * A value of 0% is completely un-saturated. A value of 100% leaves the input unchanged.
+ * Other values are linear multipliers on the effect. Values of amount over 100% are allowed, providing super-saturated results.
+ * If the ‘amount’ parameter is missing, a value of 100% is used.
+ */
+ function (value) {
+ if (typeof value === "undefined") { value = 100; }
+ this.setFilter('_saturate', 'saturate', value, '%');
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return CSS3Filters;
+ })();
+ Components.CSS3Filters = CSS3Filters;
+ })(Phaser.Components || (Phaser.Components = {}));
+ var Components = Phaser.Components;
+})(Phaser || (Phaser = {}));
///
/**
* Phaser - StageScaleMode
@@ -14843,6 +15126,11 @@ var Phaser;
* @type {number}
*/
this.height = 0;
+ /**
+ * The maximum number of times it will try to resize the canvas to fill the browser (default is 10)
+ * @type {number}
+ */
+ this.maxIterations = 10;
this._game = game;
this.enterLandscape = new Phaser.Signal();
this.enterPortrait = new Phaser.Signal();
@@ -14994,8 +15282,8 @@ var Phaser;
window.scrollTo(0, 0);
}
}
- if(this._check == null) {
- this._iterations = 10;
+ if(this._check == null && this.maxIterations > 0) {
+ this._iterations = this.maxIterations;
this._check = window.setInterval(function () {
return _this.setScreenSize();
}, 10);
@@ -15348,6 +15636,7 @@ var Phaser;
})(Phaser || (Phaser = {}));
///
///
+///
///
///
///
@@ -15413,6 +15702,7 @@ var Phaser;
event.preventDefault();
};
this.context = this.canvas.getContext('2d');
+ this.css3 = new Phaser.Components.CSS3Filters(this.canvas);
this.scaleMode = Phaser.StageScaleMode.NO_SCALE;
this.scale = new Phaser.StageScaleMode(this._game, width, height);
this.getOffset(this.canvas);
@@ -15453,8 +15743,13 @@ var Phaser;
function () {
this.scale.update();
if(this.clear) {
- // implement dirty rect? could take up more cpu time than it saves. needs benching.
- this.context.clearRect(0, 0, this.width, this.height);
+ // A 'fix' for the horrendous Android stock browser bug: https://code.google.com/p/android/issues/detail?id=39247
+ if(this._game.device.android && this._game.device.chrome == false) {
+ this.context.fillStyle = 'rgb(0,0,0)';
+ this.context.fillRect(0, 0, this.width, this.height);
+ } else {
+ this.context.clearRect(0, 0, this.width, this.height);
+ }
}
if(this._game.paused && this.scale.incorrectOrientation) {
this.orientationScreen.update();
@@ -19618,6 +19913,7 @@ var Phaser;
///
///
///
+///
///
///
///
@@ -19790,6 +20086,7 @@ var Phaser;
}, 13);
} else {
this.device = new Phaser.Device();
+ this.net = new Phaser.Net(this);
this.motion = new Phaser.Motion(this);
this.math = new Phaser.GameMath(this);
this.stage = new Phaser.Stage(this, parent, width, height);