object
and next
to null
.
*/
function LinkedList() {
this.object = null;
this.next = null;
}
LinkedList.prototype.destroy = /**
* Clean up memory.
*/
function () {
this.object = null;
if(this.next != null) {
this.next.destroy();
}
this.next = null;
};
return LinkedList;
})();
Phaser.LinkedList = LinkedList;
})(Phaser || (Phaser = {}));
var __extends = this.__extends || function (d, b) {
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
/// myFunction(Object1:GameObject,Object2:GameObject)
that is called whenever two objects are found to overlap in world space, and either no processCallback is specified, or the processCallback returns true.
* @param {Function} processCallback A function with the form myFunction(Object1:GameObject,Object2:GameObject):bool
that is called whenever two objects are found to overlap in world space. The notifyCallback is only called if this function returns true. See GameObject.separate().
* @param context The context in which the callbacks will be called
*/
function (objectOrGroup1, objectOrGroup2, notifyCallback, processCallback, context) {
if (typeof objectOrGroup2 === "undefined") { objectOrGroup2 = null; }
if (typeof notifyCallback === "undefined") { notifyCallback = null; }
if (typeof processCallback === "undefined") { processCallback = null; }
if (typeof context === "undefined") { context = null; }
this.add(objectOrGroup1, QuadTree.A_LIST);
if(objectOrGroup2 != null) {
this.add(objectOrGroup2, QuadTree.B_LIST);
QuadTree._useBothLists = true;
} else {
QuadTree._useBothLists = false;
}
QuadTree._notifyCallback = notifyCallback;
QuadTree._processingCallback = processCallback;
QuadTree._callbackContext = context;
};
QuadTree.prototype.add = /**
* Call this function to add an object to the root of the tree.
* This function will recursively add all group members, but
* not the groups themselves.
*
* @param {} objectOrGroup GameObjects are just added, Groups are recursed and their applicable members added accordingly.
* @param {Number} list A uint
flag indicating the list to which you want to add the objects. Options are QuadTree.A_LIST
and QuadTree.B_LIST
.
*/
function (objectOrGroup, list) {
QuadTree._list = list;
if(objectOrGroup.type == Phaser.Types.GROUP) {
this._i = 0;
this._members = objectOrGroup['members'];
this._l = objectOrGroup['length'];
while(this._i < this._l) {
this._basic = this._members[this._i++];
if(this._basic != null && this._basic.exists) {
if(this._basic.type == Phaser.Types.GROUP) {
this.add(this._basic, list);
} else {
QuadTree._object = this._basic;
if(QuadTree._object.exists && QuadTree._object.body.allowCollisions) {
this.addObject();
}
}
}
}
} else {
QuadTree._object = objectOrGroup;
if(QuadTree._object.exists && QuadTree._object.body.allowCollisions) {
this.addObject();
}
}
};
QuadTree.prototype.addObject = /**
* Internal function for recursively navigating and creating the tree
* while adding objects to the appropriate nodes.
*/
function () {
//If this quad (not its children) lies entirely inside this object, add it here
if(!this._canSubdivide || ((this._leftEdge >= QuadTree._object.body.bounds.x) && (this._rightEdge <= QuadTree._object.body.bounds.right) && (this._topEdge >= QuadTree._object.body.bounds.y) && (this._bottomEdge <= QuadTree._object.body.bounds.bottom))) {
this.addToList();
return;
}
//See if the selected object fits completely inside any of the quadrants
if((QuadTree._object.body.bounds.x > this._leftEdge) && (QuadTree._object.body.bounds.right < this._midpointX)) {
if((QuadTree._object.body.bounds.y > this._topEdge) && (QuadTree._object.body.bounds.bottom < this._midpointY)) {
if(this._northWestTree == null) {
this._northWestTree = new QuadTree(QuadTree.physics, this._leftEdge, this._topEdge, this._halfWidth, this._halfHeight, this);
}
this._northWestTree.addObject();
return;
}
if((QuadTree._object.body.bounds.y > this._midpointY) && (QuadTree._object.body.bounds.bottom < this._bottomEdge)) {
if(this._southWestTree == null) {
this._southWestTree = new QuadTree(QuadTree.physics, this._leftEdge, this._midpointY, this._halfWidth, this._halfHeight, this);
}
this._southWestTree.addObject();
return;
}
}
if((QuadTree._object.body.bounds.x > this._midpointX) && (QuadTree._object.body.bounds.right < this._rightEdge)) {
if((QuadTree._object.body.bounds.y > this._topEdge) && (QuadTree._object.body.bounds.bottom < this._midpointY)) {
if(this._northEastTree == null) {
this._northEastTree = new QuadTree(QuadTree.physics, this._midpointX, this._topEdge, this._halfWidth, this._halfHeight, this);
}
this._northEastTree.addObject();
return;
}
if((QuadTree._object.body.bounds.y > this._midpointY) && (QuadTree._object.body.bounds.bottom < this._bottomEdge)) {
if(this._southEastTree == null) {
this._southEastTree = new QuadTree(QuadTree.physics, this._midpointX, this._midpointY, this._halfWidth, this._halfHeight, this);
}
this._southEastTree.addObject();
return;
}
}
//If it wasn't completely contained we have to check out the partial overlaps
if((QuadTree._object.body.bounds.right > this._leftEdge) && (QuadTree._object.body.bounds.x < this._midpointX) && (QuadTree._object.body.bounds.bottom > this._topEdge) && (QuadTree._object.body.bounds.y < this._midpointY)) {
if(this._northWestTree == null) {
this._northWestTree = new QuadTree(QuadTree.physics, this._leftEdge, this._topEdge, this._halfWidth, this._halfHeight, this);
}
this._northWestTree.addObject();
}
if((QuadTree._object.body.bounds.right > this._midpointX) && (QuadTree._object.body.bounds.x < this._rightEdge) && (QuadTree._object.body.bounds.bottom > this._topEdge) && (QuadTree._object.body.bounds.y < this._midpointY)) {
if(this._northEastTree == null) {
this._northEastTree = new QuadTree(QuadTree.physics, this._midpointX, this._topEdge, this._halfWidth, this._halfHeight, this);
}
this._northEastTree.addObject();
}
if((QuadTree._object.body.bounds.right > this._midpointX) && (QuadTree._object.body.bounds.x < this._rightEdge) && (QuadTree._object.body.bounds.bottom > this._midpointY) && (QuadTree._object.body.bounds.y < this._bottomEdge)) {
if(this._southEastTree == null) {
this._southEastTree = new QuadTree(QuadTree.physics, this._midpointX, this._midpointY, this._halfWidth, this._halfHeight, this);
}
this._southEastTree.addObject();
}
if((QuadTree._object.body.bounds.right > this._leftEdge) && (QuadTree._object.body.bounds.x < this._midpointX) && (QuadTree._object.body.bounds.bottom > this._midpointY) && (QuadTree._object.body.bounds.y < this._bottomEdge)) {
if(this._southWestTree == null) {
this._southWestTree = new QuadTree(QuadTree.physics, this._leftEdge, this._midpointY, this._halfWidth, this._halfHeight, this);
}
this._southWestTree.addObject();
}
};
QuadTree.prototype.addToList = /**
* Internal function for recursively adding objects to leaf lists.
*/
function () {
if(QuadTree._list == QuadTree.A_LIST) {
if(this._tailA.object != null) {
this._ot = this._tailA;
this._tailA = new Phaser.LinkedList();
this._ot.next = this._tailA;
}
this._tailA.object = QuadTree._object;
} else {
if(this._tailB.object != null) {
this._ot = this._tailB;
this._tailB = new Phaser.LinkedList();
this._ot.next = this._tailB;
}
this._tailB.object = QuadTree._object;
}
if(!this._canSubdivide) {
return;
}
if(this._northWestTree != null) {
this._northWestTree.addToList();
}
if(this._northEastTree != null) {
this._northEastTree.addToList();
}
if(this._southEastTree != null) {
this._southEastTree.addToList();
}
if(this._southWestTree != null) {
this._southWestTree.addToList();
}
};
QuadTree.prototype.execute = /**
* QuadTree
's other main function. Call this after adding objects
* using QuadTree.load()
to compare the objects that you loaded.
*
* @return {Boolean} Whether or not any overlaps were found.
*/
function () {
this._overlapProcessed = false;
if(this._headA.object != null) {
this._iterator = this._headA;
while(this._iterator != null) {
QuadTree._object = this._iterator.object;
if(QuadTree._useBothLists) {
QuadTree._iterator = this._headB;
} else {
QuadTree._iterator = this._iterator.next;
}
if(QuadTree._object.exists && (QuadTree._object.body.allowCollisions > 0) && (QuadTree._iterator != null) && (QuadTree._iterator.object != null) && QuadTree._iterator.object.exists && this.overlapNode()) {
this._overlapProcessed = true;
}
this._iterator = this._iterator.next;
}
}
//Advance through the tree by calling overlap on each child
if((this._northWestTree != null) && this._northWestTree.execute()) {
this._overlapProcessed = true;
}
if((this._northEastTree != null) && this._northEastTree.execute()) {
this._overlapProcessed = true;
}
if((this._southEastTree != null) && this._southEastTree.execute()) {
this._overlapProcessed = true;
}
if((this._southWestTree != null) && this._southWestTree.execute()) {
this._overlapProcessed = true;
}
return this._overlapProcessed;
};
QuadTree.prototype.overlapNode = /**
* A private for comparing an object against the contents of a node.
*
* @return {Boolean} Whether or not any overlaps were found.
*/
function () {
//Walk the list and check for overlaps
this._overlapProcessed = false;
while(QuadTree._iterator != null) {
if(!QuadTree._object.exists || (QuadTree._object.body.allowCollisions <= 0)) {
break;
}
this._checkObject = QuadTree._iterator.object;
if((QuadTree._object === this._checkObject) || !this._checkObject.exists || (this._checkObject.body.allowCollisions <= 0)) {
QuadTree._iterator = QuadTree._iterator.next;
continue;
}
/*
if (QuadTree.physics.checkHullIntersection(QuadTree._object.body, this._checkObject.body))
{
//Execute callback functions if they exist
if ((QuadTree._processingCallback == null) || QuadTree._processingCallback(QuadTree._object, this._checkObject))
{
this._overlapProcessed = true;
}
if (this._overlapProcessed && (QuadTree._notifyCallback != null))
{
if (QuadTree._callbackContext !== null)
{
QuadTree._notifyCallback.call(QuadTree._callbackContext, QuadTree._object, this._checkObject);
}
else
{
QuadTree._notifyCallback(QuadTree._object, this._checkObject);
}
}
}
*/
QuadTree._iterator = QuadTree._iterator.next;
}
return this._overlapProcessed;
};
return QuadTree;
})(Phaser.Rectangle);
Phaser.QuadTree = QuadTree;
})(Phaser || (Phaser = {}));
/// Frame
with specific position, size and name.
*
* @param x {number} X position within the image to cut from.
* @param y {number} Y position within the image to cut from.
* @param width {number} Width of the frame.
* @param height {number} Height of the frame.
* @param name {string} Name of this frame.
*/
function Frame(x, y, width, height, name) {
/**
* Useful for Texture Atlas files. (is set to the filename value)
*/
this.name = '';
/**
* Rotated? (not yet implemented)
*/
this.rotated = false;
/**
* Either cw or ccw, rotation is always 90 degrees.
*/
this.rotationDirection = 'cw';
//console.log('Creating Frame', name, 'x', x, 'y', y, 'width', width, 'height', height);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.name = name;
this.rotated = false;
this.trimmed = false;
}
Frame.prototype.setRotation = /**
* Set rotation of this frame. (Not yet supported!)
*/
function (rotated, rotationDirection) {
// Not yet supported
};
Frame.prototype.setTrim = /**
* Set trim of the frame.
* @param trimmed {boolean} Whether this frame trimmed or not.
* @param actualWidth {number} Actual width of this frame.
* @param actualHeight {number} Actual height of this frame.
* @param destX {number} Destination x position.
* @param destY {number} Destination y position.
* @param destWidth {number} Destination draw width.
* @param destHeight {number} Destination draw height.
*/
function (trimmed, actualWidth, actualHeight, destX, destY, destWidth, destHeight) {
//console.log('setTrim', trimmed, 'aw', actualWidth, 'ah', actualHeight, 'dx', destX, 'dy', destY, 'dw', destWidth, 'dh', destHeight);
this.trimmed = trimmed;
if(trimmed) {
this.width = actualWidth;
this.height = actualHeight;
this.sourceSizeW = actualWidth;
this.sourceSizeH = actualHeight;
this.spriteSourceSizeX = destX;
this.spriteSourceSizeY = destY;
this.spriteSourceSizeW = destWidth;
this.spriteSourceSizeH = destHeight;
}
};
return Frame;
})();
Phaser.Frame = Frame;
})(Phaser || (Phaser = {}));
/// AnimationManager
.
*
* @param parent {Sprite} Owner sprite of this manager.
*/
function AnimationManager(parent) {
/**
* Data contains animation frames.
* @type {FrameData}
*/
this._frameData = null;
/**
* When an animation frame changes you can choose to automatically update the physics bounds of the parent Sprite
* to the width and height of the new frame. If you've set a specific physics bounds that you don't want changed during
* animation then set this to false, otherwise leave it set to true.
* @type {boolean}
*/
this.autoUpdateBounds = true;
/**
* Keeps track of the current frame of animation.
*/
this.currentFrame = null;
this._parent = parent;
this.game = parent.game;
this._anims = {
};
}
AnimationManager.prototype.loadFrameData = /**
* Load animation frame data.
* @param frameData Data to be loaded.
*/
function (frameData) {
this._frameData = frameData;
this.frame = 0;
};
AnimationManager.prototype.add = /**
* Add a new animation.
* @param name {string} What this animation should be called (e.g. "run").
* @param frames {any[]} An array of numbers/strings indicating what frames to play in what order (e.g. [1, 2, 3] or ['run0', 'run1', run2]).
* @param frameRate {number} The speed in frames per second that the animation should play at (e.g. 60 fps).
* @param loop {boolean} Whether or not the animation is looped or just plays once.
* @param useNumericIndex {boolean} Use number indexes instead of string indexes?
* @return {Animation} The Animation that was created
*/
function (name, frames, frameRate, loop, useNumericIndex) {
if (typeof frames === "undefined") { frames = null; }
if (typeof frameRate === "undefined") { frameRate = 60; }
if (typeof loop === "undefined") { loop = false; }
if (typeof useNumericIndex === "undefined") { useNumericIndex = true; }
if(this._frameData == null) {
return;
}
// Create the signals the AnimationManager will emit
if(this._parent.events.onAnimationStart == null) {
this._parent.events.onAnimationStart = new Phaser.Signal();
this._parent.events.onAnimationComplete = new Phaser.Signal();
this._parent.events.onAnimationLoop = new Phaser.Signal();
}
if(frames == null) {
frames = this._frameData.getFrameIndexes();
} else {
if(this.validateFrames(frames, useNumericIndex) == false) {
throw Error('Invalid frames given to Animation ' + name);
return;
}
}
if(useNumericIndex == false) {
frames = this._frameData.getFrameIndexesByName(frames);
}
this._anims[name] = new Phaser.Animation(this.game, this._parent, this._frameData, name, frames, frameRate, loop);
this.currentAnim = this._anims[name];
this.currentFrame = this.currentAnim.currentFrame;
return this._anims[name];
};
AnimationManager.prototype.validateFrames = /**
* Check whether the frames is valid.
* @param frames {any[]} Frames to be validated.
* @param useNumericIndex {boolean} Does these frames use number indexes or string indexes?
* @return {boolean} True if they're valid, otherwise return false.
*/
function (frames, useNumericIndex) {
for(var i = 0; i < frames.length; i++) {
if(useNumericIndex == true) {
if(frames[i] > this._frameData.total) {
return false;
}
} else {
if(this._frameData.checkFrameName(frames[i]) == false) {
return false;
}
}
}
return true;
};
AnimationManager.prototype.play = /**
* Play animation with specific name.
* @param name {string} The string name of the animation you want to play.
* @param frameRate {number} FrameRate you want to specify instead of using default.
* @param loop {boolean} Whether or not the animation is looped or just plays once.
*/
function (name, frameRate, loop) {
if (typeof frameRate === "undefined") { frameRate = null; }
if(this._anims[name]) {
if(this.currentAnim == this._anims[name]) {
if(this.currentAnim.isPlaying == false) {
return this.currentAnim.play(frameRate, loop);
}
} else {
this.currentAnim = this._anims[name];
return this.currentAnim.play(frameRate, loop);
}
}
};
AnimationManager.prototype.stop = /**
* Stop animation by name.
* Current animation will be automatically set to the stopped one.
*/
function (name) {
if(this._anims[name]) {
this.currentAnim = this._anims[name];
this.currentAnim.stop();
}
};
AnimationManager.prototype.update = /**
* Update animation and parent sprite's bounds.
*/
function () {
if(this.currentAnim && this.currentAnim.update() == true) {
this.currentFrame = this.currentAnim.currentFrame;
this._parent.texture.width = this.currentFrame.width;
this._parent.texture.height = this.currentFrame.height;
}
};
Object.defineProperty(AnimationManager.prototype, "frameData", {
get: function () {
return this._frameData;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AnimationManager.prototype, "frameTotal", {
get: function () {
if(this._frameData) {
return this._frameData.total;
} else {
return -1;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(AnimationManager.prototype, "frame", {
get: function () {
return this._frameIndex;
},
set: function (value) {
if(this._frameData && this._frameData.getFrame(value) !== null) {
this.currentFrame = this._frameData.getFrame(value);
this._parent.texture.width = this.currentFrame.width;
this._parent.texture.height = this.currentFrame.height;
if(this.autoUpdateBounds && this._parent['body']) {
this._parent.body.bounds.width = this.currentFrame.width;
this._parent.body.bounds.height = this.currentFrame.height;
}
this._frameIndex = value;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(AnimationManager.prototype, "frameName", {
get: function () {
return this.currentFrame.name;
},
set: function (value) {
if(this._frameData && this._frameData.getFrameByName(value)) {
this.currentFrame = this._frameData.getFrameByName(value);
this._parent.texture.width = this.currentFrame.width;
this._parent.texture.height = this.currentFrame.height;
this._frameIndex = this.currentFrame.index;
} else {
throw new Error("Cannot set frameName: " + value);
}
},
enumerable: true,
configurable: true
});
AnimationManager.prototype.destroy = /**
* Removes all related references
*/
function () {
this._anims = {
};
this._frameData = null;
this._frameIndex = 0;
this.currentAnim = null;
this.currentFrame = null;
};
return AnimationManager;
})();
Components.AnimationManager = AnimationManager;
})(Phaser.Components || (Phaser.Components = {}));
var Components = Phaser.Components;
})(Phaser || (Phaser = {}));
/// Sprite
.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} the initial x position of the sprite.
* @param [y] {number} the initial y position of the sprite.
* @param [key] {string} Key of the graphic you want to load for this sprite.
*/
function Sprite(game, x, y, key, frame) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof key === "undefined") { key = null; }
if (typeof frame === "undefined") { frame = null; }
/**
* Sprite physics body.
*/
this.body = null;
/**
* A boolean representing if the Sprite has been modified in any way via a scale, rotate, flip or skew.
*/
this.modified = false;
/**
* x value of the object.
*/
this.x = 0;
/**
* y value of the object.
*/
this.y = 0;
/**
* z order value of the object.
*/
this.z = -1;
/**
* Render iteration counter
*/
this.renderOrderID = 0;
this.game = game;
this.type = Phaser.Types.SPRITE;
this.exists = true;
this.active = true;
this.visible = true;
this.alive = true;
this.x = x;
this.y = y;
this.z = -1;
this.group = null;
this.name = '';
this.events = new Phaser.Components.Events(this);
this.animations = new Phaser.Components.AnimationManager(this);
this.input = new Phaser.Components.InputHandler(this);
this.texture = new Phaser.Display.Texture(this);
this.transform = new Phaser.Components.TransformManager(this);
if(key !== null) {
this.texture.loadImage(key, false);
} else {
this.texture.opaque = true;
}
if(frame !== null) {
if(typeof frame == 'string') {
this.frameName = frame;
} else {
this.frame = frame;
}
}
this.worldView = new Phaser.Rectangle(x, y, this.width, this.height);
this.cameraView = new Phaser.Rectangle(x, y, this.width, this.height);
this.transform.setCache();
this.outOfBounds = false;
this.outOfBoundsAction = Phaser.Types.OUT_OF_BOUNDS_PERSIST;
// Handy proxies
this.scale = this.transform.scale;
this.alpha = this.texture.alpha;
this.origin = this.transform.origin;
this.crop = this.texture.crop;
}
Object.defineProperty(Sprite.prototype, "rotation", {
get: /**
* The rotation of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
*/
function () {
return this.transform.rotation;
},
set: /**
* Set the rotation of the sprite in degrees. Phaser uses a right-handed coordinate system, where 0 points to the right.
* The value is automatically wrapped to be between 0 and 360.
*/
function (value) {
this.transform.rotation = this.game.math.wrap(value, 360, 0);
if(this.body) {
//this.body.angle = this.game.math.degreesToRadians(this.game.math.wrap(value, 360, 0));
}
},
enumerable: true,
configurable: true
});
Sprite.prototype.bringToTop = /**
* Brings this Sprite to the top of its current Group, if set.
*/
function () {
if(this.group) {
this.group.bringToTop(this);
}
};
Object.defineProperty(Sprite.prototype, "alpha", {
get: /**
* The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque.
*/
function () {
return this.texture.alpha;
},
set: /**
* The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque.
*/
function (value) {
this.texture.alpha = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Sprite.prototype, "frame", {
get: /**
* Get the animation frame number.
*/
function () {
return this.animations.frame;
},
set: /**
* Set the animation frame by frame number.
*/
function (value) {
this.animations.frame = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Sprite.prototype, "frameName", {
get: /**
* Get the animation frame name.
*/
function () {
return this.animations.frameName;
},
set: /**
* Set the animation frame by frame name.
*/
function (value) {
this.animations.frameName = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Sprite.prototype, "width", {
get: function () {
return this.texture.width * this.transform.scale.x;
},
set: function (value) {
this.transform.scale.x = value / this.texture.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Sprite.prototype, "height", {
get: function () {
return this.texture.height * this.transform.scale.y;
},
set: function (value) {
this.transform.scale.y = value / this.texture.height;
},
enumerable: true,
configurable: true
});
Sprite.prototype.preUpdate = /**
* Pre-update is called right before update() on each object in the game loop.
*/
function () {
this.transform.update();
if(this.transform.scrollFactor.x != 1 && this.transform.scrollFactor.x != 0) {
this.worldView.x = (this.x * this.transform.scrollFactor.x) - (this.width * this.transform.origin.x);
} else {
this.worldView.x = this.x - (this.width * this.transform.origin.x);
}
if(this.transform.scrollFactor.y != 1 && this.transform.scrollFactor.y != 0) {
this.worldView.y = (this.y * this.transform.scrollFactor.y) - (this.height * this.transform.origin.y);
} else {
this.worldView.y = this.y - (this.height * this.transform.origin.y);
}
this.worldView.width = this.width;
this.worldView.height = this.height;
if(this.modified == false && (!this.transform.scale.equals(1) || !this.transform.skew.equals(0) || this.transform.rotation != 0 || this.transform.rotationOffset != 0 || this.texture.flippedX || this.texture.flippedY)) {
this.modified = true;
}
};
Sprite.prototype.update = /**
* Override this function to update your sprites position and appearance.
*/
function () {
};
Sprite.prototype.postUpdate = /**
* Automatically called after update() by the game loop for all 'alive' objects.
*/
function () {
this.animations.update();
this.checkBounds();
if(this.modified == true && this.transform.scale.equals(1) && this.transform.skew.equals(0) && this.transform.rotation == 0 && this.transform.rotationOffset == 0 && this.texture.flippedX == false && this.texture.flippedY == false) {
this.modified = false;
}
};
Sprite.prototype.checkBounds = function () {
if(Phaser.RectangleUtils.intersects(this.worldView, this.game.world.bounds)) {
this.outOfBounds = false;
} else {
if(this.outOfBounds == false) {
this.events.onOutOfBounds.dispatch(this);
}
this.outOfBounds = true;
if(this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_KILL) {
this.kill();
} else if(this.outOfBoundsAction == Phaser.Types.OUT_OF_BOUNDS_DESTROY) {
this.destroy();
}
}
};
Sprite.prototype.destroy = /**
* Clean up memory.
*/
function () {
this.input.destroy();
};
Sprite.prototype.kill = /**
* Handy for "killing" game objects.
* Default behavior is to flag them as nonexistent AND dead.
* However, if you want the "corpse" to remain in the game,
* like to animate an effect or whatever, you should override this,
* setting only alive to false, and leaving exists true.
*/
function (removeFromGroup) {
if (typeof removeFromGroup === "undefined") { removeFromGroup = false; }
this.alive = false;
this.exists = false;
if(removeFromGroup && this.group) {
this.group.remove(this);
}
this.events.onKilled.dispatch(this);
};
Sprite.prototype.revive = /**
* Handy for bringing game objects "back to life". Just sets alive and exists back to true.
* In practice, this is most often called by Object.reset()
.
*/
function () {
this.alive = true;
this.exists = true;
this.events.onRevived.dispatch(this);
};
return Sprite;
})();
Phaser.Sprite = Sprite;
})(Phaser || (Phaser = {}));
/// GameObject
overlaps this GameObject
or Group
.
* If the group has a LOT of things in it, it might be faster to use Collision.overlaps()
.
* WARNING: Currently tilemaps do NOT support screen space overlap checks!
*
* @param objectOrGroup {object} The object or group being tested.
* @param inScreenSpace {boolean} Whether to take scroll factors numbero account when checking for overlap. Default is false, or "only compare in world space."
* @param camera {Camera} Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return {boolean} Whether or not the objects overlap this.
*/
/*
static overlaps(objectOrGroup, inScreenSpace: bool = false, camera: Camera = null): bool {
if (objectOrGroup.isGroup)
{
var results: bool = false;
var i: number = 0;
var members = Sprite
, taking scaling and rotation into account.
* The coordinates must be given in world space, not local or camera space.
*
* @param sprite {Sprite} The Sprite to check. It will take scaling and rotation into account.
* @param x {Number} The x coordinate in world space.
* @param y {Number} The y coordinate in world space.
*
* @return Whether or not the point overlaps this object.
*/
function overlapsXY(sprite, x, y) {
// if rotation == 0 then just do a rect check instead!
if(sprite.transform.rotation == 0) {
return Phaser.RectangleUtils.contains(sprite.worldView, x, y);
}
if((x - sprite.transform.upperLeft.x) * (sprite.transform.upperRight.x - sprite.transform.upperLeft.x) + (y - sprite.transform.upperLeft.y) * (sprite.transform.upperRight.y - sprite.transform.upperLeft.y) < 0) {
return false;
}
if((x - sprite.transform.upperRight.x) * (sprite.transform.upperRight.x - sprite.transform.upperLeft.x) + (y - sprite.transform.upperRight.y) * (sprite.transform.upperRight.y - sprite.transform.upperLeft.y) > 0) {
return false;
}
if((x - sprite.transform.upperLeft.x) * (sprite.transform.bottomLeft.x - sprite.transform.upperLeft.x) + (y - sprite.transform.upperLeft.y) * (sprite.transform.bottomLeft.y - sprite.transform.upperLeft.y) < 0) {
return false;
}
if((x - sprite.transform.bottomLeft.x) * (sprite.transform.bottomLeft.x - sprite.transform.upperLeft.x) + (y - sprite.transform.bottomLeft.y) * (sprite.transform.bottomLeft.y - sprite.transform.upperLeft.y) > 0) {
return false;
}
return true;
};
SpriteUtils.overlapsPoint = /**
* Checks to see if the given point overlaps this Sprite
, taking scaling and rotation into account.
* The point must be given in world space, not local or camera space.
*
* @param sprite {Sprite} The Sprite to check. It will take scaling and rotation into account.
* @param point {Point} The point in world space you want to check.
*
* @return Whether or not the point overlaps this object.
*/
function overlapsPoint(sprite, point) {
return SpriteUtils.overlapsXY(sprite, point.x, point.y);
};
SpriteUtils.onScreen = /**
* Check and see if this object is currently on screen.
*
* @param camera {Camera} Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return {boolean} Whether the object is on screen or not.
*/
function onScreen(sprite, camera) {
if (typeof camera === "undefined") { camera = null; }
if(camera == null) {
camera = sprite.game.camera;
}
SpriteUtils.getScreenXY(sprite, SpriteUtils._tempPoint, camera);
return (SpriteUtils._tempPoint.x + sprite.width > 0) && (SpriteUtils._tempPoint.x < camera.width) && (SpriteUtils._tempPoint.y + sprite.height > 0) && (SpriteUtils._tempPoint.y < camera.height);
};
SpriteUtils.getScreenXY = /**
* Call this to figure out the on-screen position of the object.
*
* @param point {Point} Takes a Point
object and assigns the post-scrolled X and Y values of this object to it.
* @param camera {Camera} Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return {Point} The Point
you passed in, or a new Point
if you didn't pass one, containing the screen X and Y position of this object.
*/
function getScreenXY(sprite, point, camera) {
if (typeof point === "undefined") { point = null; }
if (typeof camera === "undefined") { camera = null; }
if(point == null) {
point = new Phaser.Point();
}
if(camera == null) {
camera = this._game.camera;
}
point.x = sprite.x - camera.x * sprite.transform.scrollFactor.x;
point.y = sprite.y - camera.y * sprite.transform.scrollFactor.y;
point.x += (point.x > 0) ? 0.0000001 : -0.0000001;
point.y += (point.y > 0) ? 0.0000001 : -0.0000001;
return point;
};
SpriteUtils.reset = /**
* Set the world bounds that this GameObject can exist within based on the size of the current game world.
*
* @param action {number} The action to take if the object hits the world bounds, either OUT_OF_BOUNDS_KILL or OUT_OF_BOUNDS_STOP
*/
/*
static setBoundsFromWorld(action?: number = GameObject.OUT_OF_BOUNDS_STOP) {
this.setBounds(this._game.world.bounds.x, this._game.world.bounds.y, this._game.world.bounds.width, this._game.world.bounds.height);
this.outOfBoundsAction = action;
}
*/
/**
* Handy for reviving game objects.
* Resets their existence flags and position.
*
* @param x {number} The new X position of this object.
* @param y {number} The new Y position of this object.
*/
function reset(sprite, x, y) {
sprite.revive();
//sprite.body.touching = Types.NONE;
//sprite.body.wasTouching = Types.NONE;
sprite.x = x;
sprite.y = y;
sprite.body.velocity.x = 0;
sprite.body.velocity.y = 0;
sprite.body.position.x = x;
sprite.body.position.y = y;
};
SpriteUtils.setBounds = /**
* Set the world bounds that this GameObject can exist within. By default a GameObject can exist anywhere
* in the world. But by setting the bounds (which are given in world dimensions, not screen dimensions)
* it can be stopped from leaving the world, or a section of it.
*
* @param x {number} x position of the bound
* @param y {number} y position of the bound
* @param width {number} width of its bound
* @param height {number} height of its bound
*/
function setBounds(x, y, width, height) {
//this.worldBounds = new Quad(x, y, width, height);
};
return SpriteUtils;
})();
Phaser.SpriteUtils = SpriteUtils;
/**
* This function creates a flat colored square image dynamically.
* @param width {number} The width of the sprite you want to generate.
* @param height {number} The height of the sprite you want to generate.
* @param [color] {number} specifies the color of the generated block. (format is 0xAARRGGBB)
* @return {Sprite} Sprite instance itself.
*/
/*
static makeGraphic(width: number, height: number, color: string = 'rgb(255,255,255)'): Sprite {
this._texture = null;
this.width = width;
this.height = height;
this.fillColor = color;
this._dynamicTexture = false;
return this;
}
*/
})(Phaser || (Phaser = {}));
/// A complementary hue is one directly opposite the color given on the color wheel
*Value returned in 0xAARRGGBB format with Alpha set to 255.
* * @param color The color to base the harmony on * * @return 0xAARRGGBB format color value */ function getComplementHarmony(color) { var hsv = ColorUtils.RGBtoHSV(color); var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); return ColorUtils.HSVtoRGB(opposite, 1.0, 1.0); }; ColorUtils.getAnalogousHarmony = /** * Returns an Analogous Color Harmony for the given color. *An Analogous harmony are hues adjacent to each other on the color wheel
*Values returned in 0xAARRGGBB format with Alpha set to 255.
* * @param color The color to base the harmony on * @param threshold Control how adjacent the colors will be (default +- 30 degrees) * * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) */ function getAnalogousHarmony(color, threshold) { if (typeof threshold === "undefined") { threshold = 30; } var hsv = ColorUtils.RGBtoHSV(color); if(threshold > 359 || threshold < 0) { throw Error("Color Warning: Invalid threshold given to getAnalogousHarmony()"); } var warmer = ColorUtils.game.math.wrapValue(hsv.hue, 359 - threshold, 359); var colder = ColorUtils.game.math.wrapValue(hsv.hue, threshold, 359); return { color1: color, color2: ColorUtils.HSVtoRGB(warmer, 1.0, 1.0), color3: ColorUtils.HSVtoRGB(colder, 1.0, 1.0), hue1: hsv.hue, hue2: warmer, hue3: colder }; }; ColorUtils.getSplitComplementHarmony = /** * Returns an Split Complement Color Harmony for the given color. *A Split Complement harmony are the two hues on either side of the color's Complement
*Values returned in 0xAARRGGBB format with Alpha set to 255.
* * @param color The color to base the harmony on * @param threshold Control how adjacent the colors will be to the Complement (default +- 30 degrees) * * @return Object containing 3 properties: color1 (the original color), color2 (the warmer analogous color) and color3 (the colder analogous color) */ function getSplitComplementHarmony(color, threshold) { if (typeof threshold === "undefined") { threshold = 30; } var hsv = ColorUtils.RGBtoHSV(color); if(threshold >= 359 || threshold <= 0) { throw Error("ColorUtils Warning: Invalid threshold given to getSplitComplementHarmony()"); } var opposite = ColorUtils.game.math.wrapValue(hsv.hue, 180, 359); var warmer = ColorUtils.game.math.wrapValue(hsv.hue, opposite - threshold, 359); var colder = ColorUtils.game.math.wrapValue(hsv.hue, opposite + threshold, 359); return { color1: color, color2: ColorUtils.HSVtoRGB(warmer, hsv.saturation, hsv.value), color3: ColorUtils.HSVtoRGB(colder, hsv.saturation, hsv.value), hue1: hsv.hue, hue2: warmer, hue3: colder }; }; ColorUtils.getTriadicHarmony = /** * Returns a Triadic Color Harmony for the given color. *A Triadic harmony are 3 hues equidistant from each other on the color wheel
*Values returned in 0xAARRGGBB format with Alpha set to 255.
* * @param color The color to base the harmony on * * @return Object containing 3 properties: color1 (the original color), color2 and color3 (the equidistant colors) */ function getTriadicHarmony(color) { var hsv = ColorUtils.RGBtoHSV(color); var triadic1 = ColorUtils.game.math.wrapValue(hsv.hue, 120, 359); var triadic2 = ColorUtils.game.math.wrapValue(triadic1, 120, 359); return { color1: color, color2: ColorUtils.HSVtoRGB(triadic1, 1.0, 1.0), color3: ColorUtils.HSVtoRGB(triadic2, 1.0, 1.0) }; }; ColorUtils.getColorInfo = /** * Returns a string containing handy information about the given color including string hex value, * RGB format information and HSL information. Each section starts on a newline, 3 lines in total. * * @param color A color value in the format 0xAARRGGBB * * @return string containing the 3 lines of information */ function getColorInfo(color) { var argb = ColorUtils.getRGB(color); var hsl = ColorUtils.RGBtoHSV(color); // Hex format var result = ColorUtils.RGBtoHexstring(color) + "\n"; // RGB format result = result.concat("Alpha: " + argb.alpha + " Red: " + argb.red + " Green: " + argb.green + " Blue: " + argb.blue) + "\n"; // HSL info result = result.concat("Hue: " + hsl.hue + " Saturation: " + hsl.saturation + " Lightnes: " + hsl.lightness); return result; }; ColorUtils.RGBtoHexstring = /** * Return a string representation of the color in the format 0xAARRGGBB * * @param color The color to get the string representation for * * @return A string of length 10 characters in the format 0xAARRGGBB */ function RGBtoHexstring(color) { var argb = ColorUtils.getRGB(color); return "0x" + ColorUtils.colorToHexstring(argb.alpha) + ColorUtils.colorToHexstring(argb.red) + ColorUtils.colorToHexstring(argb.green) + ColorUtils.colorToHexstring(argb.blue); }; ColorUtils.RGBtoWebstring = /** * Return a string representation of the color in the format #RRGGBB * * @param color The color to get the string representation for * * @return A string of length 10 characters in the format 0xAARRGGBB */ function RGBtoWebstring(color) { var argb = ColorUtils.getRGB(color); return "#" + ColorUtils.colorToHexstring(argb.red) + ColorUtils.colorToHexstring(argb.green) + ColorUtils.colorToHexstring(argb.blue); }; ColorUtils.colorToHexstring = /** * Return a string containing a hex representation of the given color * * @param color The color channel to get the hex value for, must be a value between 0 and 255) * * @return A string of length 2 characters, i.e. 255 = FF, 0 = 00 */ function colorToHexstring(color) { var digits = "0123456789ABCDEF"; var lsd = color % 16; var msd = (color - lsd) / 16; var hexified = digits.charAt(msd) + digits.charAt(lsd); return hexified; }; ColorUtils.HSVtoRGB = /** * Convert a HSV (hue, saturation, lightness) color space value to an RGB color * * @param h Hue degree, between 0 and 359 * @param s Saturation, between 0.0 (grey) and 1.0 * @param v Value, between 0.0 (black) and 1.0 * @param alpha Alpha value to set per color (between 0 and 255) * * @return 32-bit ARGB color value (0xAARRGGBB) */ function HSVtoRGB(h, s, v, alpha) { if (typeof alpha === "undefined") { alpha = 255; } var result; if(s == 0.0) { result = ColorUtils.getColor32(alpha, v * 255, v * 255, v * 255); } else { h = h / 60.0; var f = h - Math.floor(h); var p = v * (1.0 - s); var q = v * (1.0 - s * f); var t = v * (1.0 - s * (1.0 - f)); switch(Math.floor(h)) { case 0: result = ColorUtils.getColor32(alpha, v * 255, t * 255, p * 255); break; case 1: result = ColorUtils.getColor32(alpha, q * 255, v * 255, p * 255); break; case 2: result = ColorUtils.getColor32(alpha, p * 255, v * 255, t * 255); break; case 3: result = ColorUtils.getColor32(alpha, p * 255, q * 255, v * 255); break; case 4: result = ColorUtils.getColor32(alpha, t * 255, p * 255, v * 255); break; case 5: result = ColorUtils.getColor32(alpha, v * 255, p * 255, q * 255); break; default: throw new Error("ColorUtils.HSVtoRGB : Unknown color"); } } return result; }; ColorUtils.RGBtoHSV = /** * Convert an RGB color value to an object containing the HSV color space values: Hue, Saturation and Lightness * * @param color In format 0xRRGGBB * * @return Object with the properties hue (from 0 to 360), saturation (from 0 to 1.0) and lightness (from 0 to 1.0, also available under .value) */ function RGBtoHSV(color) { var rgb = ColorUtils.getRGB(color); var red = rgb.red / 255; var green = rgb.green / 255; var blue = rgb.blue / 255; var min = Math.min(red, green, blue); var max = Math.max(red, green, blue); var delta = max - min; var lightness = (max + min) / 2; var hue; var saturation; // Grey color, no chroma if(delta == 0) { hue = 0; saturation = 0; } else { if(lightness < 0.5) { saturation = delta / (max + min); } else { saturation = delta / (2 - max - min); } var delta_r = (((max - red) / 6) + (delta / 2)) / delta; var delta_g = (((max - green) / 6) + (delta / 2)) / delta; var delta_b = (((max - blue) / 6) + (delta / 2)) / delta; if(red == max) { hue = delta_b - delta_g; } else if(green == max) { hue = (1 / 3) + delta_r - delta_b; } else if(blue == max) { hue = (2 / 3) + delta_g - delta_r; } if(hue < 0) { hue += 1; } if(hue > 1) { hue -= 1; } } // Keep the value with 0 to 359 hue *= 360; hue = Math.round(hue); return { hue: hue, saturation: saturation, lightness: lightness, value: lightness }; }; ColorUtils.interpolateColor = /** * * @method interpolateColor * @param {Number} color1 * @param {Number} color2 * @param {Number} steps * @param {Number} currentStep * @param {Number} alpha * @return {Number} * @static */ function interpolateColor(color1, color2, steps, currentStep, alpha) { if (typeof alpha === "undefined") { alpha = 255; } var src1 = ColorUtils.getRGB(color1); var src2 = ColorUtils.getRGB(color2); var r = (((src2.red - src1.red) * currentStep) / steps) + src1.red; var g = (((src2.green - src1.green) * currentStep) / steps) + src1.green; var b = (((src2.blue - src1.blue) * currentStep) / steps) + src1.blue; return ColorUtils.getColor32(alpha, r, g, b); }; ColorUtils.interpolateColorWithRGB = /** * * @method interpolateColorWithRGB * @param {Number} color * @param {Number} r2 * @param {Number} g2 * @param {Number} b2 * @param {Number} steps * @param {Number} currentStep * @return {Number} * @static */ function interpolateColorWithRGB(color, r2, g2, b2, steps, currentStep) { var src = ColorUtils.getRGB(color); var r = (((r2 - src.red) * currentStep) / steps) + src.red; var g = (((g2 - src.green) * currentStep) / steps) + src.green; var b = (((b2 - src.blue) * currentStep) / steps) + src.blue; return ColorUtils.getColor(r, g, b); }; ColorUtils.interpolateRGB = /** * * @method interpolateRGB * @param {Number} r1 * @param {Number} g1 * @param {Number} b1 * @param {Number} r2 * @param {Number} g2 * @param {Number} b2 * @param {Number} steps * @param {Number} currentStep * @return {Number} * @static */ function interpolateRGB(r1, g1, b1, r2, g2, b2, steps, currentStep) { var r = (((r2 - r1) * currentStep) / steps) + r1; var g = (((g2 - g1) * currentStep) / steps) + g1; var b = (((b2 - b1) * currentStep) / steps) + b1; return ColorUtils.getColor(r, g, b); }; ColorUtils.getRandomColor = /** * Returns a random color value between black and white *Set the min value to start each channel from the given offset.
*Set the max value to restrict the maximum color used per channel
* * @param min The lowest value to use for the color * @param max The highest value to use for the color * @param alpha The alpha value of the returning color (default 255 = fully opaque) * * @return 32-bit color value with alpha */ function getRandomColor(min, max, alpha) { if (typeof min === "undefined") { min = 0; } if (typeof max === "undefined") { max = 255; } if (typeof alpha === "undefined") { alpha = 255; } // Sanity checks if(max > 255) { return ColorUtils.getColor(255, 255, 255); } if(min > max) { return ColorUtils.getColor(255, 255, 255); } var red = min + Math.round(Math.random() * (max - min)); var green = min + Math.round(Math.random() * (max - min)); var blue = min + Math.round(Math.random() * (max - min)); return ColorUtils.getColor32(alpha, red, green, blue); }; ColorUtils.getRGB = /** * Return the component parts of a color as an Object with the properties alpha, red, green, blue * *Alpha will only be set if it exist in the given color (0xAARRGGBB)
* * @param color in RGB (0xRRGGBB) or ARGB format (0xAARRGGBB) * * @return Object with properties: alpha, red, green, blue */ function getRGB(color) { return { alpha: color >>> 24, red: color >> 16 & 0xFF, green: color >> 8 & 0xFF, blue: color & 0xFF }; }; ColorUtils.getWebRGB = /** * * @method getWebRGB * @param {Number} color * @return {Any} */ function getWebRGB(color) { var alpha = (color >>> 24) / 255; var red = color >> 16 & 0xFF; var green = color >> 8 & 0xFF; var blue = color & 0xFF; return 'rgba(' + red.toString() + ',' + green.toString() + ',' + blue.toString() + ',' + alpha.toString() + ')'; }; ColorUtils.getAlpha = /** * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component, as a value between 0 and 255 * * @param color In the format 0xAARRGGBB * * @return The Alpha component of the color, will be between 0 and 255 (0 being no Alpha, 255 full Alpha) */ function getAlpha(color) { return color >>> 24; }; ColorUtils.getAlphaFloat = /** * Given a native color value (in the format 0xAARRGGBB) this will return the Alpha component as a value between 0 and 1 * * @param color In the format 0xAARRGGBB * * @return The Alpha component of the color, will be between 0 and 1 (0 being no Alpha (opaque), 1 full Alpha (transparent)) */ function getAlphaFloat(color) { return (color >>> 24) / 255; }; ColorUtils.getRed = /** * Given a native color value (in the format 0xAARRGGBB) this will return the Red component, as a value between 0 and 255 * * @param color In the format 0xAARRGGBB * * @return The Red component of the color, will be between 0 and 255 (0 being no color, 255 full Red) */ function getRed(color) { return color >> 16 & 0xFF; }; ColorUtils.getGreen = /** * Given a native color value (in the format 0xAARRGGBB) this will return the Green component, as a value between 0 and 255 * * @param color In the format 0xAARRGGBB * * @return The Green component of the color, will be between 0 and 255 (0 being no color, 255 full Green) */ function getGreen(color) { return color >> 8 & 0xFF; }; ColorUtils.getBlue = /** * Given a native color value (in the format 0xAARRGGBB) this will return the Blue component, as a value between 0 and 255 * * @param color In the format 0xAARRGGBB * * @return The Blue component of the color, will be between 0 and 255 (0 being no color, 255 full Blue) */ function getBlue(color) { return color & 0xFF; }; return ColorUtils; })(); Phaser.ColorUtils = ColorUtils; })(Phaser || (Phaser = {})); ///DynamicTexture
.
*
* @param game {Phaser.Game} Current game instance.
* @param width {number} Init width of this texture.
* @param height {number} Init height of this texture.
*/
function DynamicTexture(game, width, height) {
this._sx = 0;
this._sy = 0;
this._sw = 0;
this._sh = 0;
this._dx = 0;
this._dy = 0;
this._dw = 0;
this._dh = 0;
/**
* You can set a globalCompositeOperation that will be applied before the render method is called on this Sprite.
* This is useful if you wish to apply an effect like 'lighten'.
* If this value is set it will call a canvas context save and restore before and after the render pass, so use it sparingly.
* Set to null to disable.
*/
this.globalCompositeOperation = null;
this.game = game;
this.type = Phaser.Types.GEOMSPRITE;
this.canvas = document.createElement('canvas');
this.canvas.width = width;
this.canvas.height = height;
this.context = this.canvas.getContext('2d');
this.css3 = new Phaser.Display.CSS3Filters(this.canvas);
this.bounds = new Phaser.Rectangle(0, 0, width, height);
}
DynamicTexture.prototype.getPixel = /**
* Get a color of a specific pixel.
* @param x {number} X position of the pixel in this texture.
* @param y {number} Y position of the pixel in this texture.
* @return {number} A native color value integer (format: 0xRRGGBB)
*/
function (x, y) {
//r = imageData.data[0];
//g = imageData.data[1];
//b = imageData.data[2];
//a = imageData.data[3];
var imageData = this.context.getImageData(x, y, 1, 1);
return Phaser.ColorUtils.getColor(imageData.data[0], imageData.data[1], imageData.data[2]);
};
DynamicTexture.prototype.getPixel32 = /**
* Get a color of a specific pixel (including alpha value).
* @param x {number} X position of the pixel in this texture.
* @param y {number} Y position of the pixel in this texture.
* @return A native color value integer (format: 0xAARRGGBB)
*/
function (x, y) {
var imageData = this.context.getImageData(x, y, 1, 1);
return Phaser.ColorUtils.getColor32(imageData.data[3], imageData.data[0], imageData.data[1], imageData.data[2]);
};
DynamicTexture.prototype.getPixels = /**
* Get pixels in array in a specific Rectangle.
* @param rect {Rectangle} The specific Rectangle.
* @returns {array} CanvasPixelArray.
*/
function (rect) {
return this.context.getImageData(rect.x, rect.y, rect.width, rect.height);
};
DynamicTexture.prototype.setPixel = /**
* Set color of a specific pixel.
* @param x {number} X position of the target pixel.
* @param y {number} Y position of the target pixel.
* @param color {number} Native integer with color value. (format: 0xRRGGBB)
*/
function (x, y, color) {
this.context.fillStyle = color;
this.context.fillRect(x, y, 1, 1);
};
DynamicTexture.prototype.setPixel32 = /**
* Set color (with alpha) of a specific pixel.
* @param x {number} X position of the target pixel.
* @param y {number} Y position of the target pixel.
* @param color {number} Native integer with color value. (format: 0xAARRGGBB)
*/
function (x, y, color) {
this.context.fillStyle = color;
this.context.fillRect(x, y, 1, 1);
};
DynamicTexture.prototype.setPixels = /**
* Set image data to a specific Rectangle.
* @param rect {Rectangle} Target Rectangle.
* @param input {object} Source image data.
*/
function (rect, input) {
this.context.putImageData(input, rect.x, rect.y);
};
DynamicTexture.prototype.fillRect = /**
* Fill a given Rectangle with specific color.
* @param rect {Rectangle} Target Rectangle you want to fill.
* @param color {number} A native number with color value. (format: 0xRRGGBB)
*/
function (rect, color) {
this.context.fillStyle = color;
this.context.fillRect(rect.x, rect.y, rect.width, rect.height);
};
DynamicTexture.prototype.pasteImage = /**
*
*/
function (key, frame, destX, destY, destWidth, destHeight) {
if (typeof frame === "undefined") { frame = -1; }
if (typeof destX === "undefined") { destX = 0; }
if (typeof destY === "undefined") { destY = 0; }
if (typeof destWidth === "undefined") { destWidth = null; }
if (typeof destHeight === "undefined") { destHeight = null; }
var texture = null;
var frameData;
this._sx = 0;
this._sy = 0;
this._dx = destX;
this._dy = destY;
// TODO - Load a frame from a sprite sheet, otherwise we'll draw the whole lot
if(frame > -1) {
//if (this.game.cache.isSpriteSheet(key))
//{
// texture = this.game.cache.getImage(key);
//this.animations.loadFrameData(this.game.cache.getFrameData(key));
//}
} else {
texture = this.game.cache.getImage(key);
this._sw = texture.width;
this._sh = texture.height;
this._dw = texture.width;
this._dh = texture.height;
}
if(destWidth !== null) {
this._dw = destWidth;
}
if(destHeight !== null) {
this._dh = destHeight;
}
if(texture != null) {
this.context.drawImage(texture, // Source Image
this._sx, // Source X (location within the source image)
this._sy, // Source Y
this._sw, // Source Width
this._sh, // Source Height
this._dx, // Destination X (where on the canvas it'll be drawn)
this._dy, // Destination Y
this._dw, // Destination Width (always same as Source Width unless scaled)
this._dh);
// Destination Height (always same as Source Height unless scaled)
}
};
DynamicTexture.prototype.copyPixels = // TODO - Add in support for: alphaBitmapData: BitmapData = null, alphaPoint: Point = null, mergeAlpha: bool = false
/**
* Copy pixel from another DynamicTexture to this texture.
* @param sourceTexture {DynamicTexture} Source texture object.
* @param sourceRect {Rectangle} The specific region Rectangle to be copied to this in the source.
* @param destPoint {Point} Top-left point the target image data will be paste at.
*/
function (sourceTexture, sourceRect, destPoint) {
// Swap for drawImage if the sourceRect is the same size as the sourceTexture to avoid a costly getImageData call
if(Phaser.RectangleUtils.equals(sourceRect, this.bounds) == true) {
this.context.drawImage(sourceTexture.canvas, destPoint.x, destPoint.y);
} else {
this.context.putImageData(sourceTexture.getPixels(sourceRect), destPoint.x, destPoint.y);
}
};
DynamicTexture.prototype.add = function (sprite) {
sprite.texture.canvas = this.canvas;
sprite.texture.context = this.context;
};
DynamicTexture.prototype.assignCanvasToGameObjects = /**
* Given an array of Sprites it will update each of them so that their canvas/contexts reference this DynamicTexture
* @param objects {Array} An array of GameObjects, or objects that inherit from it such as Sprites
*/
function (objects) {
for(var i = 0; i < objects.length; i++) {
if(objects[i].texture) {
objects[i].texture.canvas = this.canvas;
objects[i].texture.context = this.context;
}
}
};
DynamicTexture.prototype.clear = /**
* Clear the whole canvas.
*/
function () {
this.context.clearRect(0, 0, this.bounds.width, this.bounds.height);
};
DynamicTexture.prototype.render = /**
* Renders this DynamicTexture to the Stage at the given x/y coordinates
*
* @param x {number} The X coordinate to render on the stage to (given in screen coordinates, not world)
* @param y {number} The Y coordinate to render on the stage to (given in screen coordinates, not world)
*/
function (x, y) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if(this.globalCompositeOperation) {
this.game.stage.context.save();
this.game.stage.context.globalCompositeOperation = this.globalCompositeOperation;
}
this.game.stage.context.drawImage(this.canvas, x, y);
if(this.globalCompositeOperation) {
this.game.stage.context.restore();
}
};
Object.defineProperty(DynamicTexture.prototype, "width", {
get: function () {
return this.bounds.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DynamicTexture.prototype, "height", {
get: function () {
return this.bounds.height;
},
enumerable: true,
configurable: true
});
return DynamicTexture;
})();
Phaser.DynamicTexture = DynamicTexture;
})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
/// WARNING: If the group has a maxSize that has already been met, * the object will NOT be added to the group!
* * @param {Basic} Object The object you want to add to the group. * @return {Basic} The same object that was passed in. */ function (object) { // Is this object already in another Group? // You can't add a Group to itself or an object to the same Group twice if(object.group && (object.group.ID == this.ID || (object.type == Phaser.Types.GROUP && object.ID == this.ID))) { return object; } // First, look for a null entry where we can add the object. this._i = 0; this._length = this.members.length; while(this._i < this._length) { if(this.members[this._i] == null) { this.members[this._i] = object; this.setObjectIDs(object); if(this._i >= this.length) { this.length = this._i + 1; } return object; } this._i++; } // Failing that, expand the array (if we can) and add the object. if(this._maxSize > 0) { if(this.members.length >= this._maxSize) { return object; } else if(this.members.length * 2 <= this._maxSize) { this.members.length *= 2; } else { this.members.length = this._maxSize; } } else { this.members.length *= 2; } // If we made it this far, then we successfully grew the group, // and we can go ahead and add the object at the first open slot. this.members[this._i] = object; this.length = this._i + 1; this.setObjectIDs(object); return object; }; Group.prototype.addNewSprite = /** * Create a new Sprite within this Group at the specified position. * * @param x {number} X position of the new sprite. * @param y {number} Y position of the new sprite. * @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this sprite * @param [frame] {string|number} If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name. * @returns {Sprite} The newly created sprite object. */ function (x, y, key, frame) { if (typeof key === "undefined") { key = ''; } if (typeof frame === "undefined") { frame = null; } return this.add(new Phaser.Sprite(this.game, x, y, key, frame)); }; Group.prototype.setObjectIDs = /** * Sets all of the game object properties needed to exist within this Group. */ function (object, zIndex) { if (typeof zIndex === "undefined") { zIndex = -1; } // If the object is already in another Group, inform that Group it has left if(object.group !== null) { object.group.remove(object); } object.group = this; if(zIndex == -1) { zIndex = this.getNextZIndex(); } object.z = zIndex; if(object['events']) { object['events'].onAddedToGroup.dispatch(object, this, object.z); } }; Group.prototype.recycle = /** * Recycling is designed to help you reuse game objects without always re-allocating or "newing" them. * *If you specified a maximum size for this group (like in Emitter), * then recycle will employ what we're calling "rotating" recycling. * Recycle() will first check to see if the group is at capacity yet. * If group is not yet at capacity, recycle() returns a new object. * If the group IS at capacity, then recycle() just returns the next object in line.
* *If you did NOT specify a maximum size for this group, * then recycle() will employ what we're calling "grow-style" recycling. * Recycle() will return either the first object with exists == false, * or, finding none, add a new object to the array, * doubling the size of the array if necessary.
* *WARNING: If this function needs to create a new object, * and no object class was provided, it will return null * instead of a valid object!
* * @param {class} ObjectClass The class type you want to recycle (e.g. Basic, EvilRobot, etc). Do NOT "new" the class in the parameter! * * @return {any} A reference to the object that was created. Don't forget to cast it back to the Class you want (e.g. myObject = myGroup.recycle(myObjectClass) as myObjectClass;). */ function (objectClass) { if (typeof objectClass === "undefined") { objectClass = null; } if(this._maxSize > 0) { if(this.length < this._maxSize) { if(objectClass == null) { return null; } return this.add(new objectClass(this.game)); } else { this._member = this.members[this._marker++]; if(this._marker >= this._maxSize) { this._marker = 0; } return this._member; } } else { this._member = this.getFirstAvailable(objectClass); if(this._member != null) { return this._member; } if(objectClass == null) { return null; } return this.add(new objectClass(this.game)); } }; Group.prototype.remove = /** * Removes an object from the group. * * @param {Basic} object The Game Object you want to remove. * @param {boolean} splice Whether the object should be cut from the array entirely or not. * * @return {Basic} The removed object. */ function (object, splice) { if (typeof splice === "undefined") { splice = false; } //console.log('removing from group: ', object.name); this._i = this.members.indexOf(object); if(this._i < 0 || (this._i >= this.members.length)) { return null; } if(splice) { this.members.splice(this._i, 1); this.length--; } else { this.members[this._i] = null; } //console.log('nulled'); if(object['events']) { object['events'].onRemovedFromGroup.dispatch(object, this); } object.group = null; object.z = -1; return object; }; Group.prototype.replace = /** * Replaces an existing game object in this Group with a new one. * * @param {Basic} oldObject The object you want to replace. * @param {Basic} newObject The new object you want to use instead. * * @return {Basic} The new object. */ function (oldObject, newObject) { this._i = this.members.indexOf(oldObject); if(this._i < 0 || (this._i >= this.members.length)) { return null; } this.setObjectIDs(newObject, this.members[this._i].z); // Null the old object this.remove(this.members[this._i]); this.members[this._i] = newObject; return newObject; }; Group.prototype.swap = /** * Swaps two existing game object in this Group with each other. * * @param {Basic} child1 The first object to swap. * @param {Basic} child2 The second object to swap. * * @return {Basic} True if the two objects successfully swapped position. */ function (child1, child2, sort) { if (typeof sort === "undefined") { sort = true; } if(child1.group.ID != this.ID || child2.group.ID != this.ID || child1 === child2) { return false; } var tempZ = child1.z; child1.z = child2.z; child2.z = tempZ; if(sort) { this.sort(); } return true; }; Group.prototype.bringToTop = function (child) { //console.log('bringToTop', child.name,'current z', child.z); var oldZ = child.z; // If child not in this group, or is already at the top of the group, return false //if (!child || child.group == null || child.group.ID != this.ID || child.z == this._zCounter) if(!child || child.group == null || child.group.ID != this.ID) { //console.log('If child not in this group, or is already at the top of the group, return false'); return false; } // Find out the largest z index var topZ = -1; for(var i = 0; i < this.length; i++) { if(this.members[i] && this.members[i].z > topZ) { topZ = this.members[i].z; } } // Child is already at the top if(child.z == topZ) { return false; } child.z = topZ + 1; // Sort them out based on the current z indexes this.sort(); // Now tidy-up the z indexes, removing gaps, etc for(var i = 0; i < this.length; i++) { if(this.members[i]) { this.members[i].z = i; } } //console.log('bringToTop', child.name, 'old z', oldZ, 'new z', child.z); return true; // What's the z index of the top most child? /* var childIndex: number = this._zCounter; console.log('childIndex', childIndex); this._i = 0; while (this._i < this.length) { this._member = this.members[this._i++]; if (this._member) { if (this._i > childIndex) { this._member.z--; } else if (this._member.z == child.z) { childIndex = this._i; this._member.z = this._zCounter; } } } console.log('child inserted at index', child.z); // Maybe redundant? this.sort(); return true; */ }; Group.prototype.sort = /** * Call this function to sort the group according to a particular value and order. * For example, to sort game objects for Zelda-style overlaps you might call *myGroup.sort("y",Group.ASCENDING)
at the bottom of your
* State.update()
override. To sort all existing objects after
* a big explosion or bomb attack, you might call myGroup.sort("exists",Group.DESCENDING)
.
*
* @param {string} index The string
name of the member variable you want to sort on. Default value is "z".
* @param {number} order A Group
constant that defines the sort order. Possible values are Group.ASCENDING
and Group.DESCENDING
. Default value is Group.ASCENDING
.
*/
function (index, order) {
if (typeof index === "undefined") { index = 'z'; }
if (typeof order === "undefined") { order = Group.ASCENDING; }
var _this = this;
this._sortIndex = index;
this._sortOrder = order;
this.members.sort(function (a, b) {
return _this.sortHandler(a, b);
});
};
Group.prototype.sortHandler = /**
* Helper function for the sort process.
*
* @param {Basic} Obj1 The first object being sorted.
* @param {Basic} Obj2 The second object being sorted.
*
* @return {number} An integer value: -1 (Obj1 before Obj2), 0 (same), or 1 (Obj1 after Obj2).
*/
function (obj1, obj2) {
if(!obj1 || !obj2) {
//console.log('null objects in sort', obj1, obj2);
return 0;
}
if(obj1[this._sortIndex] < obj2[this._sortIndex]) {
return this._sortOrder;
} else if(obj1[this._sortIndex] > obj2[this._sortIndex]) {
return -this._sortOrder;
}
return 0;
};
Group.prototype.setAll = /**
* Go through and set the specified variable to the specified value on all members of the group.
*
* @param {string} VariableName The string representation of the variable name you want to modify, for example "visible" or "scrollFactor".
* @param {Object} Value The value you want to assign to that variable.
* @param {boolean} Recurse Default value is true, meaning if setAll()
encounters a member that is a group, it will call setAll()
on that group rather than modifying its variable.
*/
function (variableName, value, recurse) {
if (typeof recurse === "undefined") { recurse = true; }
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null) {
if(recurse && this._member.type == Phaser.Types.GROUP) {
this._member.setAll(variableName, value, recurse);
} else {
this._member[variableName] = value;
}
}
}
};
Group.prototype.callAll = /**
* Go through and call the specified function on all members of the group.
* Currently only works on functions that have no required parameters.
*
* @param {string} FunctionName The string representation of the function you want to call on each object, for example "kill()" or "init()".
* @param {boolean} Recurse Default value is true, meaning if callAll()
encounters a member that is a group, it will call callAll()
on that group rather than calling the group's function.
*/
function (functionName, recurse) {
if (typeof recurse === "undefined") { recurse = true; }
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null) {
if(recurse && this._member.type == Phaser.Types.GROUP) {
this._member.callAll(functionName, recurse);
} else {
this._member[functionName]();
}
}
}
};
Group.prototype.forEach = /**
* @param {function} callback
* @param {boolean} recursive
*/
function (callback, recursive) {
if (typeof recursive === "undefined") { recursive = false; }
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null) {
if(recursive && this._member.type == Phaser.Types.GROUP) {
this._member.forEach(callback, true);
} else {
callback.call(this, this._member);
}
}
}
};
Group.prototype.forEachAlive = /**
* @param {any} context
* @param {function} callback
* @param {boolean} recursive
*/
function (context, callback, recursive) {
if (typeof recursive === "undefined") { recursive = false; }
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null && this._member.alive) {
if(recursive && this._member.type == Phaser.Types.GROUP) {
this._member.forEachAlive(context, callback, true);
} else {
callback.call(context, this._member);
}
}
}
};
Group.prototype.getFirstAvailable = /**
* Call this function to retrieve the first object with exists == false in the group.
* This is handy for recycling in general, e.g. respawning enemies.
*
* @param {any} [ObjectClass] An optional parameter that lets you narrow the results to instances of this particular class.
*
* @return {any} A Basic
currently flagged as not existing.
*/
function (objectClass) {
if (typeof objectClass === "undefined") { objectClass = null; }
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if((this._member != null) && !this._member.exists && ((objectClass == null) || (typeof this._member === objectClass))) {
return this._member;
}
}
return null;
};
Group.prototype.getFirstNull = /**
* Call this function to retrieve the first index set to 'null'.
* Returns -1 if no index stores a null object.
*
* @return {number} An int
indicating the first null slot in the group.
*/
function () {
this._i = 0;
while(this._i < this.length) {
if(this.members[this._i] == null) {
return this._i;
} else {
this._i++;
}
}
return -1;
};
Group.prototype.getFirstExtant = /**
* Call this function to retrieve the first object with exists == true in the group.
* This is handy for checking if everything's wiped out, or choosing a squad leader, etc.
*
* @return {Basic} A Basic
currently flagged as existing.
*/
function () {
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null && this._member.exists) {
return this._member;
}
}
return null;
};
Group.prototype.getFirstAlive = /**
* Call this function to retrieve the first object with dead == false in the group.
* This is handy for checking if everything's wiped out, or choosing a squad leader, etc.
*
* @return {Basic} A Basic
currently flagged as not dead.
*/
function () {
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if((this._member != null) && this._member.exists && this._member.alive) {
return this._member;
}
}
return null;
};
Group.prototype.getFirstDead = /**
* Call this function to retrieve the first object with dead == true in the group.
* This is handy for checking if everything's wiped out, or choosing a squad leader, etc.
*
* @return {Basic} A Basic
currently flagged as dead.
*/
function () {
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if((this._member != null) && !this._member.alive) {
return this._member;
}
}
return null;
};
Group.prototype.countLiving = /**
* Call this function to find out how many members of the group are not dead.
*
* @return {number} The number of Basic
s flagged as not dead. Returns -1 if group is empty.
*/
function () {
this._count = -1;
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null) {
if(this._count < 0) {
this._count = 0;
}
if(this._member.exists && this._member.alive) {
this._count++;
}
}
}
return this._count;
};
Group.prototype.countDead = /**
* Call this function to find out how many members of the group are dead.
*
* @return {number} The number of Basic
s flagged as dead. Returns -1 if group is empty.
*/
function () {
this._count = -1;
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if(this._member != null) {
if(this._count < 0) {
this._count = 0;
}
if(!this._member.alive) {
this._count++;
}
}
}
return this._count;
};
Group.prototype.getRandom = /**
* Returns a member at random from the group.
*
* @param {number} StartIndex Optional offset off the front of the array. Default value is 0, or the beginning of the array.
* @param {number} Length Optional restriction on the number of values you want to randomly select from.
*
* @return {Basic} A Basic
from the members list.
*/
function (startIndex, length) {
if (typeof startIndex === "undefined") { startIndex = 0; }
if (typeof length === "undefined") { length = 0; }
if(length == 0) {
length = this.length;
}
return this.game.math.getRandom(this.members, startIndex, length);
};
Group.prototype.clear = /**
* Remove all instances of Basic
subclass (Basic, Block, etc) from the list.
* WARNING: does not destroy() or kill() any of these objects!
*/
function () {
this.length = this.members.length = 0;
};
Group.prototype.kill = /**
* Calls kill on the group's members and then on the group itself.
*/
function () {
this._i = 0;
while(this._i < this.length) {
this._member = this.members[this._i++];
if((this._member != null) && this._member.exists) {
this._member.kill();
}
}
};
return Group;
})();
Phaser.Group = Group;
})(Phaser || (Phaser = {}));
/// If binding was added using `Signal.addOnce()` it will be automatically removed from signal dispatch queue, this method is used internally for the signal dispatch.
* @param {Array} [paramsArr] Array of parameters that should be passed to the listener * @return {*} Value returned by the listener. */ function (paramsArr) { var handlerReturn; var params; if(this.active && !!this._listener) { params = this.params ? this.params.concat(paramsArr) : paramsArr; handlerReturn = this._listener.apply(this.context, params); if(this._isOnce) { this.detach(); } } return handlerReturn; }; SignalBinding.prototype.detach = /** * Detach binding from signal. * - alias to: mySignal.remove(myBinding.getListener()); * @return {Function|null} Handler function bound to the signal or `null` if binding was previously detached. */ function () { return this.isBound() ? this._signal.remove(this._listener, this.context) : null; }; SignalBinding.prototype.isBound = /** * @return {Boolean} `true` if binding is still bound to the signal and have a listener. */ function () { return (!!this._signal && !!this._listener); }; SignalBinding.prototype.isOnce = /** * @return {boolean} If SignalBinding will only be executed once. */ function () { return this._isOnce; }; SignalBinding.prototype.getListener = /** * @return {Function} Handler function bound to the signal. */ function () { return this._listener; }; SignalBinding.prototype.getSignal = /** * @return {Signal} Signal that listener is currently bound to. */ function () { return this._signal; }; SignalBinding.prototype._destroy = /** * Delete instance properties * @private */ function () { delete this._signal; delete this._listener; delete this.context; }; SignalBinding.prototype.toString = /** * @return {string} String representation of the object. */ function () { return '[SignalBinding isOnce:' + this._isOnce + ', isBound:' + this.isBound() + ', active:' + this.active + ']'; }; return SignalBinding; })(); Phaser.SignalBinding = SignalBinding; })(Phaser || (Phaser = {})); ///IMPORTANT: Setting this property during a dispatch will only affect the next dispatch, if you want to stop the propagation of a signal use `halt()` instead.
* @type boolean */ this.active = true; } Signal.VERSION = '1.0.0'; Signal.prototype.validateListener = /** * * @method validateListener * @param {Any} listener * @param {Any} fnName */ function (listener, fnName) { if(typeof listener !== 'function') { throw new Error('listener is a required param of {fn}() and should be a Function.'.replace('{fn}', fnName)); } }; Signal.prototype._registerListener = /** * @param {Function} listener * @param {boolean} isOnce * @param {Object} [listenerContext] * @param {Number} [priority] * @return {SignalBinding} * @private */ function (listener, isOnce, listenerContext, priority) { var prevIndex = this._indexOfListener(listener, listenerContext); var binding; if(prevIndex !== -1) { binding = this._bindings[prevIndex]; if(binding.isOnce() !== isOnce) { throw new Error('You cannot add' + (isOnce ? '' : 'Once') + '() then add' + (!isOnce ? '' : 'Once') + '() the same listener without removing the relationship first.'); } } else { binding = new Phaser.SignalBinding(this, listener, isOnce, listenerContext, priority); this._addBinding(binding); } if(this.memorize && this._prevParams) { binding.execute(this._prevParams); } return binding; }; Signal.prototype._addBinding = /** * * @method _addBinding * @param {SignalBinding} binding * @private */ function (binding) { //simplified insertion sort var n = this._bindings.length; do { --n; }while(this._bindings[n] && binding.priority <= this._bindings[n].priority); this._bindings.splice(n + 1, 0, binding); }; Signal.prototype._indexOfListener = /** * * @method _indexOfListener * @param {Function} listener * @return {number} * @private */ function (listener, context) { var n = this._bindings.length; var cur; while(n--) { cur = this._bindings[n]; if(cur.getListener() === listener && cur.context === context) { return n; } } return -1; }; Signal.prototype.has = /** * Check if listener was attached to Signal. * @param {Function} listener * @param {Object} [context] * @return {boolean} if Signal has the specified listener. */ function (listener, context) { if (typeof context === "undefined") { context = null; } return this._indexOfListener(listener, context) !== -1; }; Signal.prototype.add = /** * Add a listener to the signal. * @param {Function} listener Signal handler function. * @param {Object} [listenerContext] Context on which listener will be executed (object that should represent the `this` variable inside listener function). * @param {Number} [priority] The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0) * @return {SignalBinding} An Object representing the binding between the Signal and listener. */ function (listener, listenerContext, priority) { if (typeof listenerContext === "undefined") { listenerContext = null; } if (typeof priority === "undefined") { priority = 0; } this.validateListener(listener, 'add'); return this._registerListener(listener, false, listenerContext, priority); }; Signal.prototype.addOnce = /** * Add listener to the signal that should be removed after first execution (will be executed only once). * @param {Function} listener Signal handler function. * @param {Object} [listenerContext] Context on which listener will be executed (object that should represent the `this` variable inside listener function). * @param {Number} [priority] The priority level of the event listener. Listeners with higher priority will be executed before listeners with lower priority. Listeners with same priority level will be executed at the same order as they were added. (default = 0) * @return {SignalBinding} An Object representing the binding between the Signal and listener. */ function (listener, listenerContext, priority) { if (typeof listenerContext === "undefined") { listenerContext = null; } if (typeof priority === "undefined") { priority = 0; } this.validateListener(listener, 'addOnce'); return this._registerListener(listener, true, listenerContext, priority); }; Signal.prototype.remove = /** * Remove a single listener from the dispatch queue. * @param {Function} listener Handler function that should be removed. * @param {Object} [context] Execution context (since you can add the same handler multiple times if executing in a different context). * @return {Function} Listener handler function. */ function (listener, context) { if (typeof context === "undefined") { context = null; } this.validateListener(listener, 'remove'); var i = this._indexOfListener(listener, context); if(i !== -1) { this._bindings[i]._destroy(); this._bindings.splice(i, 1); } return listener; }; Signal.prototype.removeAll = /** * Remove all listeners from the Signal. */ function () { if(this._bindings) { var n = this._bindings.length; while(n--) { this._bindings[n]._destroy(); } this._bindings.length = 0; } }; Signal.prototype.getNumListeners = /** * @return {number} Number of listeners attached to the Signal. */ function () { return this._bindings.length; }; Signal.prototype.halt = /** * Stop propagation of the event, blocking the dispatch to next listeners on the queue. *IMPORTANT: should be called only during signal dispatch, calling it before/after dispatch won't affect signal broadcast.
* @see Signal.prototype.disable */ function () { this._shouldPropagate = false; }; Signal.prototype.dispatch = /** * Dispatch/Broadcast Signal to all listeners added to the queue. * @param {...*} [params] Parameters that should be passed to each handler. */ function () { var paramsArr = []; for (var _i = 0; _i < (arguments.length - 0); _i++) { paramsArr[_i] = arguments[_i + 0]; } if(!this.active) { return; } var n = this._bindings.length; var bindings; if(this.memorize) { this._prevParams = paramsArr; } if(!n) { //should come after memorize return; } bindings = this._bindings.slice(0)//clone array in case add/remove items during dispatch ; this._shouldPropagate = true//in case `halt` was called before dispatch or during the previous dispatch. ; //execute all callbacks until end of the list or until a callback returns `false` or stops propagation //reverse loop since listeners with higher priority will be added at the end of the list do { n--; }while(bindings[n] && this._shouldPropagate && bindings[n].execute(paramsArr) !== false); }; Signal.prototype.forget = /** * Forget memorized arguments. * @see Signal.memorize */ function () { this._prevParams = null; }; Signal.prototype.dispose = /** * Remove all bindings from signal and destroy any reference to external objects (destroy Signal object). *IMPORTANT: calling any method on the signal instance after calling dispose will throw errors.
*/ function () { this.removeAll(); delete this._bindings; delete this._prevParams; }; Signal.prototype.toString = /** * @return {string} String representation of the object. */ function () { return '[Signal active:' + this.active + ' numListeners:' + this.getNumListeners() + ']'; }; return Signal; })(); Phaser.Signal = Signal; })(Phaser || (Phaser = {})); ///* Returns true or false based on the chance value (default 50%). For example if you wanted a player to have a 30% chance * of getting a bonus, call chanceRoll(30) - true means the chance passed, false means it failed. *
* @param chance The chance of receiving the value. A number between 0 and 100 (effectively 0% to 100%) * @return true if the roll passed, or false */ function (chance) { if (typeof chance === "undefined") { chance = 50; } if(chance <= 0) { return false; } else if(chance >= 100) { return true; } else { if(Math.random() * 100 >= chance) { return false; } else { return true; } } }; GameMath.prototype.maxAdd = /** * Adds the given amount to the value, but never lets the value go over the specified maximum * * @param value The value to add the amount to * @param amount The amount to add to the value * @param max The maximum the value is allowed to be * @return The new value */ function (value, amount, max) { value += amount; if(value > max) { value = max; } return value; }; GameMath.prototype.minSub = /** * Subtracts the given amount from the value, but never lets the value go below the specified minimum * * @param value The base value * @param amount The amount to subtract from the base value * @param min The minimum the value is allowed to be * @return The new value */ function (value, amount, min) { value -= amount; if(value < min) { value = min; } return value; }; GameMath.prototype.wrapValue = /** * Adds value to amount and ensures that the result always stays between 0 and max, by wrapping the value around. *Values must be positive integers, and are passed through Math.abs
* * @param value The value to add the amount to * @param amount The amount to add to the value * @param max The maximum the value is allowed to be * @return The wrapped value */ function (value, amount, max) { var diff; value = Math.abs(value); amount = Math.abs(amount); max = Math.abs(max); diff = (value + amount) % max; return diff; }; GameMath.prototype.randomSign = /** * Randomly returns either a 1 or -1 * * @return 1 or -1 */ function () { return (Math.random() > 0.5) ? 1 : -1; }; GameMath.prototype.isOdd = /** * Returns true if the number given is odd. * * @param n The number to check * * @return True if the given number is odd. False if the given number is even. */ function (n) { if(n & 1) { return true; } else { return false; } }; GameMath.prototype.isEven = /** * Returns true if the number given is even. * * @param n The number to check * * @return True if the given number is even. False if the given number is odd. */ function (n) { if(n & 1) { return false; } else { return true; } }; GameMath.prototype.wrapAngle = /** * Keeps an angle value between -180 and +180* The parameters allow you to specify the length, amplitude and frequency of the wave. Once you have called this function * you should get the results via getSinTable() and getCosTable(). This generator is fast enough to be used in real-time. *
* @param length The length of the wave * @param sinAmplitude The amplitude to apply to the sine table (default 1.0) if you need values between say -+ 125 then give 125 as the value * @param cosAmplitude The amplitude to apply to the cosine table (default 1.0) if you need values between say -+ 125 then give 125 as the value * @param frequency The frequency of the sine and cosine table data * @return Returns the sine table * @see getSinTable * @see getCosTable */ function (length, sinAmplitude, cosAmplitude, frequency) { if (typeof sinAmplitude === "undefined") { sinAmplitude = 1.0; } if (typeof cosAmplitude === "undefined") { cosAmplitude = 1.0; } if (typeof frequency === "undefined") { frequency = 1.0; } var sin = sinAmplitude; var cos = cosAmplitude; var frq = frequency * Math.PI / length; this.cosTable = []; this.sinTable = []; for(var c = 0; c < length; c++) { cos -= sin * frq; sin += cos * frq; this.cosTable[c] = cos; this.sinTable[c] = sin; } return this.sinTable; }; GameMath.prototype.shiftSinTable = /** * Shifts through the sin table data by one value and returns it. * This effectively moves the position of the data from the start to the end of the table. * @return The sin value. */ function () { if(this.sinTable) { var s = this.sinTable.shift(); this.sinTable.push(s); return s; } }; GameMath.prototype.shiftCosTable = /** * Shifts through the cos table data by one value and returns it. * This effectively moves the position of the data from the start to the end of the table. * @return The cos value. */ function () { if(this.cosTable) { var s = this.cosTable.shift(); this.cosTable.push(s); return s; } }; GameMath.prototype.shuffleArray = /** * Shuffles the data in the given array into a new order * @param array The array to shuffle * @return The array */ function (array) { for(var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; }; GameMath.prototype.distanceBetween = /** * Returns the distance from this Point object to the given Point object. * @method distanceFrom * @param {Point} target - The destination Point object. * @param {Boolean} round - Round the distance to the nearest integer (default false) * @return {Number} The distance between this Point object and the destination Point object. **/ function (x1, y1, x2, y2) { var dx = x1 - x2; var dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); }; GameMath.prototype.vectorLength = /** * Finds the length of the given vector * * @param dx * @param dy * * @return */ function (dx, dy) { return Math.sqrt(dx * dx + dy * dy); }; return GameMath; })(); Phaser.GameMath = GameMath; })(Phaser || (Phaser = {})); ///Camera
with position and size.
*
* @param x {number} X Position of the created camera.
* @param y {number} y Position of the created camera.
* @param width {number} Width of the created camera.
* @param height {number} Height of the created camera.
*/
function CameraManager(game, x, y, width, height) {
/**
* Local helper stores index of next created camera.
*/
this._cameraInstance = 0;
/**
* Helper for sort.
*/
this._sortIndex = '';
this._game = game;
this._cameras = [];
this.defaultCamera = this.addCamera(x, y, width, height);
this.current = this.defaultCamera;
}
CameraManager.CAMERA_TYPE_ORTHOGRAPHIC = 0;
CameraManager.CAMERA_TYPE_ISOMETRIC = 1;
CameraManager.prototype.getAll = /**
* Get all the cameras.
*
* @returns {Camera[]} An array contains all the cameras.
*/
function () {
return this._cameras;
};
CameraManager.prototype.update = /**
* Update cameras.
*/
function () {
for(var i = 0; i < this._cameras.length; i++) {
this._cameras[i].update();
}
};
CameraManager.prototype.postUpdate = /**
* postUpdate cameras.
*/
function () {
for(var i = 0; i < this._cameras.length; i++) {
this._cameras[i].postUpdate();
}
};
CameraManager.prototype.addCamera = /**
* Create a new camera with specific position and size.
*
* @param x {number} X position of the new camera.
* @param y {number} Y position of the new camera.
* @param width {number} Width of the new camera.
* @param height {number} Height of the new camera.
* @returns {Camera} The newly created camera object.
*/
function (x, y, width, height, type) {
if (typeof type === "undefined") { type = CameraManager.CAMERA_TYPE_ORTHOGRAPHIC; }
var newCam = new Phaser.Camera(this._game, this._cameraInstance, x, y, width, height);
this._cameras.push(newCam);
this._cameraInstance++;
return newCam;
};
CameraManager.prototype.removeCamera = /**
* Remove a new camera with its id.
*
* @param id {number} ID of the camera you want to remove.
* @returns {boolean} True if successfully removed the camera, otherwise return false.
*/
function (id) {
for(var c = 0; c < this._cameras.length; c++) {
if(this._cameras[c].ID == id) {
if(this.current.ID === this._cameras[c].ID) {
this.current = null;
}
this._cameras.splice(c, 1);
return true;
}
}
return false;
};
CameraManager.prototype.swap = function (camera1, camera2, sort) {
if (typeof sort === "undefined") { sort = true; }
if(camera1.ID == camera2.ID) {
return false;
}
var tempZ = camera1.z;
camera1.z = camera2.z;
camera2.z = tempZ;
if(sort) {
this.sort();
}
return true;
};
CameraManager.prototype.sort = /**
* Call this function to sort the Cameras according to a particular value and order (default is their Z value).
* The order in which they are sorted determines the render order. If sorted on z then Cameras with a lower z-index value render first.
*
* @param {string} index The string
name of the Camera variable you want to sort on. Default value is "z".
* @param {number} order A Group
constant that defines the sort order. Possible values are Group.ASCENDING
and Group.DESCENDING
. Default value is Group.ASCENDING
.
*/
function (index, order) {
if (typeof index === "undefined") { index = 'z'; }
if (typeof order === "undefined") { order = Phaser.Group.ASCENDING; }
var _this = this;
this._sortIndex = index;
this._sortOrder = order;
this._cameras.sort(function (a, b) {
return _this.sortHandler(a, b);
});
};
CameraManager.prototype.sortHandler = /**
* Helper function for the sort process.
*
* @param {Basic} Obj1 The first object being sorted.
* @param {Basic} Obj2 The second object being sorted.
*
* @return {number} An integer value: -1 (Obj1 before Obj2), 0 (same), or 1 (Obj1 after Obj2).
*/
function (obj1, obj2) {
if(obj1[this._sortIndex] < obj2[this._sortIndex]) {
return this._sortOrder;
} else if(obj1[this._sortIndex] > obj2[this._sortIndex]) {
return -this._sortOrder;
}
return 0;
};
CameraManager.prototype.destroy = /**
* Clean up memory.
*/
function () {
this._cameras.length = 0;
this.current = this.addCamera(0, 0, this._game.stage.width, this._game.stage.height);
};
return CameraManager;
})();
Phaser.CameraManager = CameraManager;
})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
/// Tween
.
*
* @param object {object} Target object will be affected by this tween.
* @param game {Phaser.Game} Current game instance.
*/
function Tween(object, game) {
/**
* Reference to the target object.
* @type {object}
*/
this._object = null;
this._pausedTime = 0;
/**
* Start values container.
* @type {object}
*/
this._valuesStart = {
};
/**
* End values container.
* @type {object}
*/
this._valuesEnd = {
};
/**
* How long this tween will perform.
* @type {number}
*/
this._duration = 1000;
this._delayTime = 0;
this._startTime = null;
/**
* Will this tween automatically restart when it completes?
* @type {boolean}
*/
this._loop = false;
/**
* A yoyo tween is one that plays once fully, then reverses back to the original tween values before completing.
* @type {boolean}
*/
this._yoyo = false;
this._yoyoCount = 0;
/**
* Contains chained tweens.
* @type {Tweens[]}
*/
this._chainedTweens = [];
this.isRunning = false;
this._object = object;
this._game = game;
this._manager = this._game.tweens;
this._interpolationFunction = this._game.math.linearInterpolation;
this._easingFunction = Phaser.Easing.Linear.None;
this._chainedTweens = [];
this.onStart = new Phaser.Signal();
this.onUpdate = new Phaser.Signal();
this.onComplete = new Phaser.Signal();
}
Tween.prototype.to = /**
* Configure the Tween
* @param properties {object} Propertis you want to tween.
* @param [duration] {number} duration of this tween.
* @param [ease] {any} Easing function.
* @param [autoStart] {boolean} Whether this tween will start automatically or not.
* @param [delay] {number} delay before this tween will start, defaults to 0 (no delay)
* @param [loop] {boolean} Should the tween automatically restart once complete? (ignores any chained tweens)
* @return {Tween} Itself.
*/
function (properties, duration, ease, autoStart, delay, loop, yoyo) {
if (typeof duration === "undefined") { duration = 1000; }
if (typeof ease === "undefined") { ease = null; }
if (typeof autoStart === "undefined") { autoStart = false; }
if (typeof delay === "undefined") { delay = 0; }
if (typeof loop === "undefined") { loop = false; }
if (typeof yoyo === "undefined") { yoyo = false; }
this._duration = duration;
// If properties isn't an object this will fail, sanity check it here somehow?
this._valuesEnd = properties;
if(ease !== null) {
this._easingFunction = ease;
}
if(delay > 0) {
this._delayTime = delay;
}
this._loop = loop;
this._yoyo = yoyo;
this._yoyoCount = 0;
if(autoStart === true) {
return this.start();
} else {
return this;
}
};
Tween.prototype.loop = function (value) {
this._loop = value;
return this;
};
Tween.prototype.yoyo = function (value) {
this._yoyo = value;
this._yoyoCount = 0;
return this;
};
Tween.prototype.start = /**
* Start to tween.
*/
function (looped) {
if (typeof looped === "undefined") { looped = false; }
if(this._game === null || this._object === null) {
return;
}
if(looped == false) {
this._manager.add(this);
this.onStart.dispatch(this._object);
}
this._startTime = this._game.time.now + this._delayTime;
this.isRunning = true;
for(var property in this._valuesEnd) {
// This prevents the interpolation of null values or of non-existing properties
if(this._object[property] === null || !(property in this._object)) {
throw Error('Phaser.Tween interpolation of null value of non-existing property');
continue;
}
// check if an Array was provided as property value
if(this._valuesEnd[property] instanceof Array) {
if(this._valuesEnd[property].length === 0) {
continue;
}
// create a local copy of the Array with the start value at the front
this._valuesEnd[property] = [
this._object[property]
].concat(this._valuesEnd[property]);
}
if(looped == false) {
this._valuesStart[property] = this._object[property];
}
}
return this;
};
Tween.prototype.reverse = function () {
var tempObj = {
};
for(var property in this._valuesStart) {
tempObj[property] = this._valuesStart[property];
this._valuesStart[property] = this._valuesEnd[property];
this._valuesEnd[property] = tempObj[property];
}
this._yoyoCount++;
return this.start(true);
};
Tween.prototype.reset = function () {
// Reset the properties back to what they were before
for(var property in this._valuesStart) {
this._object[property] = this._valuesStart[property];
}
return this.start(true);
};
Tween.prototype.clear = function () {
this._chainedTweens = [];
this.onStart.removeAll();
this.onUpdate.removeAll();
this.onComplete.removeAll();
return this;
};
Tween.prototype.stop = /**
* Stop tweening.
*/
function () {
if(this._manager !== null) {
this._manager.remove(this);
}
this.isRunning = false;
this.onComplete.dispose();
return this;
};
Object.defineProperty(Tween.prototype, "parent", {
set: function (value) {
this._game = value;
this._manager = this._game.tweens;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Tween.prototype, "delay", {
get: function () {
return this._delayTime;
},
set: function (amount) {
this._delayTime = amount;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Tween.prototype, "easing", {
get: function () {
return this._easingFunction;
},
set: function (easing) {
this._easingFunction = easing;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Tween.prototype, "interpolation", {
get: function () {
return this._interpolationFunction;
},
set: function (interpolation) {
this._interpolationFunction = interpolation;
},
enumerable: true,
configurable: true
});
Tween.prototype.chain = /**
* Add another chained tween, which will start automatically when the one before it completes.
* @param tween {Phaser.Tween} Tween object you want to chain with this.
* @return {Phaser.Tween} Itselfe.
*/
function (tween) {
this._chainedTweens.push(tween);
return this;
};
Tween.prototype.update = /**
* Update tweening.
* @param time {number} Current time from game clock.
* @return {boolean} Return false if this completed and no need to update, otherwise return true.
*/
function (time) {
if(this._game.paused == true) {
if(this._pausedTime == 0) {
this._pausedTime = time;
}
} else {
// Ok we aren't paused, but was there some time gained?
if(this._pausedTime > 0) {
this._startTime += (time - this._pausedTime);
this._pausedTime = 0;
}
}
if(time < this._startTime) {
return true;
}
this._tempElapsed = (time - this._startTime) / this._duration;
this._tempElapsed = this._tempElapsed > 1 ? 1 : this._tempElapsed;
this._tempValue = this._easingFunction(this._tempElapsed);
for(var property in this._valuesStart) {
// Add checks for object, array, numeric up front
if(this._valuesEnd[property] instanceof Array) {
this._object[property] = this._interpolationFunction(this._valuesEnd[property], this._tempValue);
} else {
this._object[property] = this._valuesStart[property] + (this._valuesEnd[property] - this._valuesStart[property]) * this._tempValue;
}
}
this.onUpdate.dispatch(this._object, this._tempValue);
if(this._tempElapsed == 1) {
// Yoyo?
if(this._yoyo) {
if(this._yoyoCount == 0) {
// Reverse the tween
this.reverse();
return true;
} else {
// We've yoyo'd once already, quit?
if(this._loop == false) {
this.onComplete.dispatch(this._object);
for(var i = 0; i < this._chainedTweens.length; i++) {
this._chainedTweens[i].start();
}
return false;
}
}
}
// Loop?
if(this._loop) {
this._yoyoCount = 0;
this.reset();
return true;
} else {
this.onComplete.dispatch(this._object);
for(var i = 0; i < this._chainedTweens.length; i++) {
this._chainedTweens[i].start();
}
if(this._chainedTweens.length == 0) {
this.isRunning = false;
}
return false;
}
}
return true;
};
return Tween;
})();
Phaser.Tween = Tween;
})(Phaser || (Phaser = {}));
/// Sprite
, all meaningful creation
* happens during loadGraphic()
or makeGraphic()
or whatever.
*/
function ArcadeParticle(game) {
_super.call(this, game);
this.body.type = Phaser.Types.BODY_DYNAMIC;
this.lifespan = 0;
}
ArcadeParticle.prototype.update = /**
* The particle's main update logic. Basically it checks to see if it should be dead yet.
*/
function () {
// Lifespan behavior
if(this.lifespan <= 0) {
return;
}
this.lifespan -= this.game.time.elapsed;
if(this.lifespan <= 0) {
this.kill();
}
};
ArcadeParticle.prototype.onEmit = /**
* Triggered whenever this object is launched by a Emitter
.
* You can override this to add custom behavior like a sound or AI or something.
*/
function () {
};
return ArcadeParticle;
})(Phaser.Sprite);
Phaser.ArcadeParticle = ArcadeParticle;
})(Phaser || (Phaser = {}));
/// Emitter
object at a specific position.
* Does NOT automatically generate or attach particles!
*
* @param x {number} The X position of the emitter.
* @param y {number} The Y position of the emitter.
* @param [size] {number} Specifies a maximum capacity for this emitter.
*/
function ArcadeEmitter(game, x, y, size) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof size === "undefined") { size = 0; }
_super.call(this, game, size);
this.x = x;
this.y = y;
this.width = 0;
this.height = 0;
this.minParticleSpeed = new Phaser.Vec2(-100, -100);
this.maxParticleSpeed = new Phaser.Vec2(100, 100);
this.minRotation = -360;
this.maxRotation = 360;
this.gravity = 0;
this.particleClass = null;
this.particleDrag = new Phaser.Vec2();
this.frequency = 0.1;
this.lifespan = 3;
this.bounce = 0;
this._quantity = 0;
this._counter = 0;
this._explode = true;
this.on = false;
this.exists = true;
this.active = true;
this.visible = true;
}
ArcadeEmitter.prototype.destroy = /**
* Clean up memory.
*/
function () {
this.minParticleSpeed = null;
this.maxParticleSpeed = null;
this.particleDrag = null;
this.particleClass = null;
this._point = null;
_super.prototype.destroy.call(this);
};
ArcadeEmitter.prototype.makeParticles = /**
* This function generates a new array of particle sprites to attach to the emitter.
*
* @param graphics If you opted to not pre-configure an array of Sprite objects, you can simply pass in a particle image or sprite sheet.
* @param quantity {number} The number of particles to generate when using the "create from image" option.
* @param multiple {boolean} Whether the image in the Graphics param is a single particle or a bunch of particles (if it's a bunch, they need to be square!).
* @param collide {number} Whether the particles should be flagged as not 'dead' (non-colliding particles are higher performance). 0 means no collisions, 0-1 controls scale of particle's bounding box.
*
* @return This Emitter instance (nice for chaining stuff together, if you're into that).
*/
function (graphics, quantity, multiple, collide) {
if (typeof quantity === "undefined") { quantity = 50; }
if (typeof multiple === "undefined") { multiple = false; }
if (typeof collide === "undefined") { collide = 0; }
this.maxSize = quantity;
var totalFrames = 1;
/*
if(Multiple)
{
var sprite:Sprite = new Sprite(this.game);
sprite.loadGraphic(Graphics,true);
totalFrames = sprite.frames;
sprite.destroy();
}
*/
var randomFrame;
var particle;
var i = 0;
while(i < quantity) {
if(this.particleClass == null) {
particle = new Phaser.ArcadeParticle(this.game);
} else {
particle = new this.particleClass(this.game);
}
if(multiple) {
/*
randomFrame = this.game.math.random()*totalFrames;
*/
} else {
if(graphics) {
particle.texture.loadImage(graphics);
}
}
if(collide > 0) {
//particle.body.allowCollisions = Types.ANY;
particle.body.type = Phaser.Types.BODY_DYNAMIC;
particle.width *= collide;
particle.height *= collide;
} else {
//particle.body.allowCollisions = Types.NONE;
}
particle.exists = false;
// Center the origin for rotation assistance
//particle.transform.origin.setTo(particle.body.bounds.halfWidth, particle.body.bounds.halfHeight);
this.add(particle);
i++;
}
return this;
};
ArcadeEmitter.prototype.preUpdate = function () {
};
ArcadeEmitter.prototype.postUpdate = function () {
};
ArcadeEmitter.prototype.update = /**
* Called automatically by the game loop, decides when to launch particles and when to "die".
*/
function () {
if(this.on) {
if(this._explode) {
this.on = false;
var i = 0;
var l = this._quantity;
if((l <= 0) || (l > this.length)) {
l = this.length;
}
while(i < l) {
this.emitParticle();
i++;
}
this._quantity = 0;
} else {
this._timer += this.game.time.elapsed;
while((this.frequency > 0) && (this._timer > this.frequency) && this.on) {
this._timer -= this.frequency;
this.emitParticle();
if((this._quantity > 0) && (++this._counter >= this._quantity)) {
this.on = false;
this._quantity = 0;
}
}
}
}
_super.prototype.update.call(this);
};
ArcadeEmitter.prototype.kill = /**
* Call this function to turn off all the particles and the emitter.
*/
function () {
this.on = false;
this.alive = false;
this.exists = false;
};
ArcadeEmitter.prototype.revive = /**
* Handy for bringing game objects "back to life". Just sets alive and exists back to true.
* In practice, this is most often called by Object.reset()
.
*/
function () {
this.alive = true;
this.exists = true;
};
ArcadeEmitter.prototype.start = /**
* Call this function to start emitting particles.
*
* @param explode {boolean} Whether the particles should all burst out at once.
* @param lifespan {number} How long each particle lives once emitted. 0 = forever.
* @param frequency {number} Ignored if Explode is set to true. Frequency is how often to emit a particle. 0 = never emit, 0.1 = 1 particle every 0.1 seconds, 5 = 1 particle every 5 seconds.
* @param quantity {number} How many particles to launch. 0 = "all of the particles".
*/
function (explode, lifespan, frequency, quantity) {
if (typeof explode === "undefined") { explode = true; }
if (typeof lifespan === "undefined") { lifespan = 0; }
if (typeof frequency === "undefined") { frequency = 0.1; }
if (typeof quantity === "undefined") { quantity = 0; }
this.revive();
this.visible = true;
this.on = true;
this._explode = explode;
this.lifespan = lifespan;
this.frequency = frequency;
this._quantity += quantity;
this._counter = 0;
this._timer = 0;
};
ArcadeEmitter.prototype.emitParticle = /**
* This function can be used both internally and externally to emit the next particle.
*/
function () {
var particle = this.recycle(Phaser.ArcadeParticle);
particle.lifespan = this.lifespan;
//particle.body.bounce.setTo(this.bounce, this.bounce);
Phaser.SpriteUtils.reset(particle, this.x - (particle.width >> 1) + this.game.rnd.integer * this.width, this.y - (particle.height >> 1) + this.game.rnd.integer * this.height);
particle.visible = true;
if(this.minParticleSpeed.x != this.maxParticleSpeed.x) {
particle.body.velocity.x = this.minParticleSpeed.x + this.game.rnd.integer * (this.maxParticleSpeed.x - this.minParticleSpeed.x);
} else {
particle.body.velocity.x = this.minParticleSpeed.x;
}
if(this.minParticleSpeed.y != this.maxParticleSpeed.y) {
particle.body.velocity.y = this.minParticleSpeed.y + this.game.rnd.integer * (this.maxParticleSpeed.y - this.minParticleSpeed.y);
} else {
particle.body.velocity.y = this.minParticleSpeed.y;
}
//particle.body.acceleration.y = this.gravity;
if(this.minRotation != this.maxRotation && this.minRotation !== 0 && this.maxRotation !== 0) {
particle.body.angularVelocity = this.minRotation + this.game.rnd.integer * (this.maxRotation - this.minRotation);
} else {
particle.body.angularVelocity = this.minRotation;
}
if(particle.body.angularVelocity != 0) {
particle.rotation = this.game.rnd.integer * 360 - 180;
}
//particle.body.drag.x = this.particleDrag.x;
//particle.body.drag.y = this.particleDrag.y;
particle.onEmit();
};
ArcadeEmitter.prototype.setSize = /**
* A more compact way of setting the width and height of the emitter.
*
* @param width {number} The desired width of the emitter (particles are spawned randomly within these dimensions).
* @param height {number} The desired height of the emitter.
*/
function (width, height) {
this.width = width;
this.height = height;
};
ArcadeEmitter.prototype.setXSpeed = /**
* A more compact way of setting the X velocity range of the emitter.
*
* @param Min {number} The minimum value for this range.
* @param Max {number} The maximum value for this range.
*/
function (min, max) {
if (typeof min === "undefined") { min = 0; }
if (typeof max === "undefined") { max = 0; }
this.minParticleSpeed.x = min;
this.maxParticleSpeed.x = max;
};
ArcadeEmitter.prototype.setYSpeed = /**
* A more compact way of setting the Y velocity range of the emitter.
*
* @param Min {number} The minimum value for this range.
* @param Max {number} The maximum value for this range.
*/
function (min, max) {
if (typeof min === "undefined") { min = 0; }
if (typeof max === "undefined") { max = 0; }
this.minParticleSpeed.y = min;
this.maxParticleSpeed.y = max;
};
ArcadeEmitter.prototype.setRotation = /**
* A more compact way of setting the angular velocity constraints of the emitter.
*
* @param Min {number} The minimum value for this range.
* @param Max {number} The maximum value for this range.
*/
function (min, max) {
if (typeof min === "undefined") { min = 0; }
if (typeof max === "undefined") { max = 0; }
this.minRotation = min;
this.maxRotation = max;
};
ArcadeEmitter.prototype.at = /**
* Change the emitter's midpoint to match the midpoint of a Object
.
*
* @param Object {object} The Object
that you want to sync up with.
*/
function (object) {
//this.x = object.body.bounds.halfWidth - (this.width >> 1);
//this.y = object.body.bounds.halfHeight - (this.height >> 1);
};
return ArcadeEmitter;
})(Phaser.Group);
Phaser.ArcadeEmitter = ArcadeEmitter;
})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
/// Button
object.
*
* @param game {Phaser.Game} Current game instance.
* @param [x] {number} X position of the button.
* @param [y] {number} Y position of the button.
* @param [key] {string} The image key as defined in the Game.Cache to use as the texture for this button.
* @param [callback] {function} The function to call when this button is pressed
* @param [callbackContext] {object} The context in which the callback will be called (usually 'this')
* @param [overFrame] {string|number} This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
* @param [outFrame] {string|number} This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
* @param [downFrame] {string|number} This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
*/
function Button(game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof key === "undefined") { key = null; }
if (typeof callback === "undefined") { callback = null; }
if (typeof callbackContext === "undefined") { callbackContext = null; }
if (typeof overFrame === "undefined") { overFrame = null; }
if (typeof outFrame === "undefined") { outFrame = null; }
if (typeof downFrame === "undefined") { downFrame = null; }
_super.call(this, game, x, y, key, outFrame);
this._onOverFrameName = null;
this._onOutFrameName = null;
this._onDownFrameName = null;
this._onUpFrameName = null;
this._onOverFrameID = null;
this._onOutFrameID = null;
this._onDownFrameID = null;
this._onUpFrameID = null;
this.type = Phaser.Types.BUTTON;
if(typeof overFrame == 'string') {
this._onOverFrameName = overFrame;
} else {
this._onOverFrameID = overFrame;
}
if(typeof outFrame == 'string') {
this._onOutFrameName = outFrame;
this._onUpFrameName = outFrame;
} else {
this._onOutFrameID = outFrame;
this._onUpFrameID = outFrame;
}
if(typeof downFrame == 'string') {
this._onDownFrameName = downFrame;
} else {
this._onDownFrameID = downFrame;
}
// These are the signals the game will subscribe to
this.onInputOver = new Phaser.Signal();
this.onInputOut = new Phaser.Signal();
this.onInputDown = new Phaser.Signal();
this.onInputUp = new Phaser.Signal();
// Set a default signal for them
if(callback) {
this.onInputUp.add(callback, callbackContext);
}
this.input.start(0, false, true);
// Redirect the input events to here so we can handle animation updates, etc
this.events.onInputOver.add(this.onInputOverHandler, this);
this.events.onInputOut.add(this.onInputOutHandler, this);
this.events.onInputDown.add(this.onInputDownHandler, this);
this.events.onInputUp.add(this.onInputUpHandler, this);
}
Button.prototype.onInputOverHandler = // TODO
//public tabIndex: number;
//public tabEnabled: bool;
// ENTER or SPACE can activate this button if it has focus
function (pointer) {
if(this._onOverFrameName != null) {
this.frameName = this._onOverFrameName;
} else if(this._onOverFrameID != null) {
this.frame = this._onOverFrameID;
}
if(this.onInputOver) {
this.onInputOver.dispatch(this, pointer);
}
};
Button.prototype.onInputOutHandler = function (pointer) {
if(this._onOutFrameName != null) {
this.frameName = this._onOutFrameName;
} else if(this._onOutFrameID != null) {
this.frame = this._onOutFrameID;
}
if(this.onInputOut) {
this.onInputOut.dispatch(this, pointer);
}
};
Button.prototype.onInputDownHandler = function (pointer) {
//console.log('Button onInputDownHandler: ' + Date.now());
if(this._onDownFrameName != null) {
this.frameName = this._onDownFrameName;
} else if(this._onDownFrameID != null) {
this.frame = this._onDownFrameID;
}
if(this.onInputDown) {
this.onInputDown.dispatch(this, pointer);
}
};
Button.prototype.onInputUpHandler = function (pointer) {
//console.log('Button onInputUpHandler: ' + Date.now());
if(this._onUpFrameName != null) {
this.frameName = this._onUpFrameName;
} else if(this._onUpFrameID != null) {
this.frame = this._onUpFrameID;
}
if(this.onInputUp) {
this.onInputUp.dispatch(this, pointer);
}
};
Object.defineProperty(Button.prototype, "priorityID", {
get: function () {
return this.input.priorityID;
},
set: function (value) {
this.input.priorityID = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Button.prototype, "useHandCursor", {
get: function () {
return this.input.useHandCursor;
},
set: function (value) {
this.input.useHandCursor = value;
},
enumerable: true,
configurable: true
});
return Button;
})(Phaser.Sprite);
UI.Button = Button;
})(Phaser.UI || (Phaser.UI = {}));
var UI = Phaser.UI;
})(Phaser || (Phaser = {}));
/// ScrollRegion
.
*
* @param x {number} X position in world coordinate.
* @param y {number} Y position in world coordinate.
* @param width {number} Width of this object.
* @param height {number} Height of this object.
* @param speedX {number} X-axis scrolling speed.
* @param speedY {number} Y-axis scrolling speed.
*/
function ScrollRegion(x, y, width, height, speedX, speedY) {
this._anchorWidth = 0;
this._anchorHeight = 0;
this._inverseWidth = 0;
this._inverseHeight = 0;
/**
* Will this region be rendered? (default to true)
* @type {boolean}
*/
this.visible = true;
// Our seamless scrolling quads
this._A = new Phaser.Rectangle(x, y, width, height);
this._B = new Phaser.Rectangle(x, y, width, height);
this._C = new Phaser.Rectangle(x, y, width, height);
this._D = new Phaser.Rectangle(x, y, width, height);
this._scroll = new Phaser.Vec2();
this._bounds = new Phaser.Rectangle(x, y, width, height);
this.scrollSpeed = new Phaser.Vec2(speedX, speedY);
}
ScrollRegion.prototype.update = /**
* Update region scrolling with tick time.
* @param delta {number} Elapsed time since last update.
*/
function (delta) {
this._scroll.x += this.scrollSpeed.x;
this._scroll.y += this.scrollSpeed.y;
if(this._scroll.x > this._bounds.right) {
this._scroll.x = this._bounds.x;
}
if(this._scroll.x < this._bounds.x) {
this._scroll.x = this._bounds.right;
}
if(this._scroll.y > this._bounds.bottom) {
this._scroll.y = this._bounds.y;
}
if(this._scroll.y < this._bounds.y) {
this._scroll.y = this._bounds.bottom;
}
// Anchor Dimensions
this._anchorWidth = (this._bounds.width - this._scroll.x) + this._bounds.x;
this._anchorHeight = (this._bounds.height - this._scroll.y) + this._bounds.y;
if(this._anchorWidth > this._bounds.width) {
this._anchorWidth = this._bounds.width;
}
if(this._anchorHeight > this._bounds.height) {
this._anchorHeight = this._bounds.height;
}
this._inverseWidth = this._bounds.width - this._anchorWidth;
this._inverseHeight = this._bounds.height - this._anchorHeight;
// Rectangle A
this._A.setTo(this._scroll.x, this._scroll.y, this._anchorWidth, this._anchorHeight);
// Rectangle B
this._B.y = this._scroll.y;
this._B.width = this._inverseWidth;
this._B.height = this._anchorHeight;
// Rectangle C
this._C.x = this._scroll.x;
this._C.width = this._anchorWidth;
this._C.height = this._inverseHeight;
// Rectangle D
this._D.width = this._inverseWidth;
this._D.height = this._inverseHeight;
};
ScrollRegion.prototype.render = /**
* Render this region to specific context.
* @param context {CanvasRenderingContext2D} Canvas context this region will be rendered to.
* @param texture {object} The texture to be rendered.
* @param dx {number} X position in world coordinate.
* @param dy {number} Y position in world coordinate.
* @param width {number} Width of this region to be rendered.
* @param height {number} Height of this region to be rendered.
*/
function (context, texture, dx, dy, dw, dh) {
if(this.visible == false) {
return;
}
// dx/dy are the world coordinates to render the FULL ScrollZone into.
// This ScrollRegion may be smaller than that and offset from the dx/dy coordinates.
this.crop(context, texture, this._A.x, this._A.y, this._A.width, this._A.height, dx, dy, dw, dh, 0, 0);
this.crop(context, texture, this._B.x, this._B.y, this._B.width, this._B.height, dx, dy, dw, dh, this._A.width, 0);
this.crop(context, texture, this._C.x, this._C.y, this._C.width, this._C.height, dx, dy, dw, dh, 0, this._A.height);
this.crop(context, texture, this._D.x, this._D.y, this._D.width, this._D.height, dx, dy, dw, dh, this._C.width, this._A.height);
//context.fillStyle = 'rgb(255,255,255)';
//context.font = '18px Arial';
//context.fillText('RectangleA: ' + this._A.toString(), 32, 450);
//context.fillText('RectangleB: ' + this._B.toString(), 32, 480);
//context.fillText('RectangleC: ' + this._C.toString(), 32, 510);
//context.fillText('RectangleD: ' + this._D.toString(), 32, 540);
};
ScrollRegion.prototype.crop = /**
* Crop part of the texture and render it to the given context.
* @param context {CanvasRenderingContext2D} Canvas context the texture will be rendered to.
* @param texture {object} Texture to be rendered.
* @param srcX {number} Target region top-left x coordinate in the texture.
* @param srcX {number} Target region top-left y coordinate in the texture.
* @param srcW {number} Target region width in the texture.
* @param srcH {number} Target region height in the texture.
* @param destX {number} Render region top-left x coordinate in the context.
* @param destX {number} Render region top-left y coordinate in the context.
* @param destW {number} Target region width in the context.
* @param destH {number} Target region height in the context.
* @param offsetX {number} X offset to the context.
* @param offsetY {number} Y offset to the context.
*/
function (context, texture, srcX, srcY, srcW, srcH, destX, destY, destW, destH, offsetX, offsetY) {
offsetX += destX;
offsetY += destY;
if(srcW > (destX + destW) - offsetX) {
srcW = (destX + destW) - offsetX;
}
if(srcH > (destY + destH) - offsetY) {
srcH = (destY + destH) - offsetY;
}
srcX = Math.floor(srcX);
srcY = Math.floor(srcY);
srcW = Math.floor(srcW);
srcH = Math.floor(srcH);
offsetX = Math.floor(offsetX + this._bounds.x);
offsetY = Math.floor(offsetY + this._bounds.y);
if(srcW > 0 && srcH > 0) {
context.drawImage(texture, srcX, srcY, srcW, srcH, offsetX, offsetY, srcW, srcH);
}
};
return ScrollRegion;
})();
Phaser.ScrollRegion = ScrollRegion;
})(Phaser || (Phaser = {}));
/// ScrollZone
.
*
* @param game {Phaser.Game} Current game instance.
* @param key {string} Asset key for image texture of this object.
* @param x {number} X position in world coordinate.
* @param y {number} Y position in world coordinate.
* @param [width] {number} width of this object.
* @param [height] {number} height of this object.
*/
function ScrollZone(game, key, x, y, width, height) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof width === "undefined") { width = 0; }
if (typeof height === "undefined") { height = 0; }
_super.call(this, game, x, y, key);
this.type = Phaser.Types.SCROLLZONE;
this.regions = [];
if(this.texture.loaded) {
if(width > this.width || height > this.height) {
// Create our repeating texture (as the source image wasn't large enough for the requested size)
this.createRepeatingTexture(width, height);
this.width = width;
this.height = height;
}
// Create a default ScrollRegion at the requested size
this.addRegion(0, 0, this.width, this.height);
// If the zone is smaller than the image itself then shrink the bounds
if((width < this.width || height < this.height) && width !== 0 && height !== 0) {
this.width = width;
this.height = height;
}
}
}
ScrollZone.prototype.addRegion = /**
* Add a new region to this zone.
* @param x {number} X position of the new region.
* @param y {number} Y position of the new region.
* @param width {number} Width of the new region.
* @param height {number} Height of the new region.
* @param [speedX] {number} x-axis scrolling speed.
* @param [speedY] {number} y-axis scrolling speed.
* @return {ScrollRegion} The newly added region.
*/
function (x, y, width, height, speedX, speedY) {
if (typeof speedX === "undefined") { speedX = 0; }
if (typeof speedY === "undefined") { speedY = 0; }
if(x > this.width || y > this.height || x < 0 || y < 0 || (x + width) > this.width || (y + height) > this.height) {
throw Error('Invalid ScrollRegion defined. Cannot be larger than parent ScrollZone');
return null;
}
this.currentRegion = new Phaser.ScrollRegion(x, y, width, height, speedX, speedY);
this.regions.push(this.currentRegion);
return this.currentRegion;
};
ScrollZone.prototype.setSpeed = /**
* Set scrolling speed of current region.
* @param x {number} X speed of current region.
* @param y {number} Y speed of current region.
*/
function (x, y) {
if(this.currentRegion) {
this.currentRegion.scrollSpeed.setTo(x, y);
}
return this;
};
ScrollZone.prototype.update = /**
* Update regions.
*/
function () {
for(var i = 0; i < this.regions.length; i++) {
this.regions[i].update(this.game.time.delta);
}
};
ScrollZone.prototype.createRepeatingTexture = /**
* Create repeating texture with _texture, and store it into the _dynamicTexture.
* Used to create texture when texture image is small than size of the zone.
*/
function (regionWidth, regionHeight) {
// Work out how many we'll need of the source image to make it tile properly
var tileWidth = Math.ceil(this.width / regionWidth) * regionWidth;
var tileHeight = Math.ceil(this.height / regionHeight) * regionHeight;
var dt = new Phaser.DynamicTexture(this.game, tileWidth, tileHeight);
dt.context.rect(0, 0, tileWidth, tileHeight);
dt.context.fillStyle = dt.context.createPattern(this.texture.imageTexture, "repeat");
dt.context.fill();
this.texture.loadDynamicTexture(dt);
};
return ScrollZone;
})(Phaser.Sprite);
Phaser.ScrollZone = ScrollZone;
})(Phaser || (Phaser = {}));
/// TilemapLayer
.
*
* @param game {Phaser.Game} Current game instance.
* @param parent {Tilemap} The tilemap that contains this layer.
* @param key {string} Asset key for this map.
* @param mapFormat {number} Format of this map data, available: Tilemap.FORMAT_CSV or Tilemap.FORMAT_TILED_JSON.
* @param name {string} Name of this layer, so you can get this layer by its name.
* @param tileWidth {number} Width of tiles in this map.
* @param tileHeight {number} Height of tiles in this map.
*/
function TilemapLayer(game, parent, key, mapFormat, name, tileWidth, tileHeight) {
/**
* Controls whether update() and draw() are automatically called.
* @type {boolean}
*/
this.exists = true;
/**
* Controls whether draw() are automatically called.
* @type {boolean}
*/
this.visible = true;
/**
* How many tiles in each row.
* Read-only variable, do NOT recommend changing after the map is loaded!
* @type {number}
*/
this.widthInTiles = 0;
/**
* How many tiles in each column.
* Read-only variable, do NOT recommend changing after the map is loaded!
* @type {number}
*/
this.heightInTiles = 0;
/**
* Read-only variable, do NOT recommend changing after the map is loaded!
* @type {number}
*/
this.widthInPixels = 0;
/**
* Read-only variable, do NOT recommend changing after the map is loaded!
* @type {number}
*/
this.heightInPixels = 0;
/**
* Distance between REAL tiles to the tileset texture bound.
* @type {number}
*/
this.tileMargin = 0;
/**
* Distance between every 2 neighbor tile in the tileset texture.
* @type {number}
*/
this.tileSpacing = 0;
this.game = game;
this.parent = parent;
this.name = name;
this.mapFormat = mapFormat;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.boundsInTiles = new Phaser.Rectangle();
this.texture = new Phaser.Display.Texture(this);
this.transform = new Phaser.Components.TransformManager(this);
if(key !== null) {
this.texture.loadImage(key, false);
} else {
this.texture.opaque = true;
}
// Handy proxies
this.alpha = this.texture.alpha;
this.mapData = [];
this._tempTileBlock = [];
}
TilemapLayer.prototype.putTileWorldXY = /**
* Set a specific tile with its x and y in tiles.
* @param x {number} X position of this tile in world coordinates.
* @param y {number} Y position of this tile in world coordinates.
* @param index {number} The index of this tile type in the core map data.
*/
function (x, y, index) {
x = this.game.math.snapToFloor(x, this.tileWidth) / this.tileWidth;
y = this.game.math.snapToFloor(y, this.tileHeight) / this.tileHeight;
if(y >= 0 && y < this.mapData.length) {
if(x >= 0 && x < this.mapData[y].length) {
this.mapData[y][x] = index;
}
}
};
TilemapLayer.prototype.putTile = /**
* Set a specific tile with its x and y in tiles.
* @param x {number} X position of this tile.
* @param y {number} Y position of this tile.
* @param index {number} The index of this tile type in the core map data.
*/
function (x, y, index) {
if(y >= 0 && y < this.mapData.length) {
if(x >= 0 && x < this.mapData[y].length) {
this.mapData[y][x] = index;
}
}
};
TilemapLayer.prototype.swapTile = /**
* Swap tiles with 2 kinds of indexes.
* @param tileA {number} First tile index.
* @param tileB {number} Second tile index.
* @param [x] {number} specify a Rectangle of tiles to operate. The x position in tiles of Rectangle's left-top corner.
* @param [y] {number} specify a Rectangle of tiles to operate. The y position in tiles of Rectangle's left-top corner.
* @param [width] {number} specify a Rectangle of tiles to operate. The width in tiles.
* @param [height] {number} specify a Rectangle of tiles to operate. The height in tiles.
*/
function (tileA, tileB, x, y, width, height) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof width === "undefined") { width = this.widthInTiles; }
if (typeof height === "undefined") { height = this.heightInTiles; }
this.getTempBlock(x, y, width, height);
for(var r = 0; r < this._tempTileBlock.length; r++) {
// First sweep marking tileA as needing a new index
if(this._tempTileBlock[r].tile.index == tileA) {
this._tempTileBlock[r].newIndex = true;
}
// In the same pass we can swap tileB to tileA
if(this._tempTileBlock[r].tile.index == tileB) {
this.mapData[this._tempTileBlock[r].y][this._tempTileBlock[r].x] = tileA;
}
}
for(var r = 0; r < this._tempTileBlock.length; r++) {
// And now swap our newIndex tiles for tileB
if(this._tempTileBlock[r].newIndex == true) {
this.mapData[this._tempTileBlock[r].y][this._tempTileBlock[r].x] = tileB;
}
}
};
TilemapLayer.prototype.fillTile = /**
* Fill a tile block with a specific tile index.
* @param index {number} Index of tiles you want to fill with.
* @param [x] {number} x position (in tiles) of block's left-top corner.
* @param [y] {number} y position (in tiles) of block's left-top corner.
* @param [width] {number} width of block.
* @param [height] {number} height of block.
*/
function (index, x, y, width, height) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof width === "undefined") { width = this.widthInTiles; }
if (typeof height === "undefined") { height = this.heightInTiles; }
this.getTempBlock(x, y, width, height);
for(var r = 0; r < this._tempTileBlock.length; r++) {
this.mapData[this._tempTileBlock[r].y][this._tempTileBlock[r].x] = index;
}
};
TilemapLayer.prototype.randomiseTiles = /**
* Set random tiles to a specific tile block.
* @param tiles {number[]} Tiles with indexes in this array will be randomly set to the given block.
* @param [x] {number} x position (in tiles) of block's left-top corner.
* @param [y] {number} y position (in tiles) of block's left-top corner.
* @param [width] {number} width of block.
* @param [height] {number} height of block.
*/
function (tiles, x, y, width, height) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof width === "undefined") { width = this.widthInTiles; }
if (typeof height === "undefined") { height = this.heightInTiles; }
this.getTempBlock(x, y, width, height);
for(var r = 0; r < this._tempTileBlock.length; r++) {
this.mapData[this._tempTileBlock[r].y][this._tempTileBlock[r].x] = this.game.math.getRandom(tiles);
}
};
TilemapLayer.prototype.replaceTile = /**
* Replace one kind of tiles to another kind.
* @param tileA {number} Index of tiles you want to replace.
* @param tileB {number} Index of tiles you want to set.
* @param [x] {number} x position (in tiles) of block's left-top corner.
* @param [y] {number} y position (in tiles) of block's left-top corner.
* @param [width] {number} width of block.
* @param [height] {number} height of block.
*/
function (tileA, tileB, x, y, width, height) {
if (typeof x === "undefined") { x = 0; }
if (typeof y === "undefined") { y = 0; }
if (typeof width === "undefined") { width = this.widthInTiles; }
if (typeof height === "undefined") { height = this.heightInTiles; }
this.getTempBlock(x, y, width, height);
for(var r = 0; r < this._tempTileBlock.length; r++) {
if(this._tempTileBlock[r].tile.index == tileA) {
this.mapData[this._tempTileBlock[r].y][this._tempTileBlock[r].x] = tileB;
}
}
};
TilemapLayer.prototype.getTileBlock = /**
* Get a tile block with specific position and size.(both are in tiles)
* @param x {number} X position of block's left-top corner.
* @param y {number} Y position of block's left-top corner.
* @param width {number} Width of block.
* @param height {number} Height of block.
*/
function (x, y, width, height) {
var output = [];
this.getTempBlock(x, y, width, height);
for(var r = 0; r < this._tempTileBlock.length; r++) {
output.push({
x: this._tempTileBlock[r].x,
y: this._tempTileBlock[r].y,
tile: this._tempTileBlock[r].tile
});
}
return output;
};
TilemapLayer.prototype.getTileFromWorldXY = /**
* Get a tile with specific position (in world coordinate). (thus you give a position of a point which is within the tile)
* @param x {number} X position of the point in target tile.
* @param x {number} Y position of the point in target tile.
*/
function (x, y) {
x = this.game.math.snapToFloor(x, this.tileWidth) / this.tileWidth;
y = this.game.math.snapToFloor(y, this.tileHeight) / this.tileHeight;
return this.getTileIndex(x, y);
};
TilemapLayer.prototype.getTileOverlaps = /**
* Get tiles overlaps the given object.
* @param object {GameObject} Tiles you want to get that overlaps this.
* @return {array} Array with tiles informations. (Each contains x, y and the tile.)
*/
function (object) {
// If the object is outside of the world coordinates then abort the check (tilemap has to exist within world bounds)
if(object.body.bounds.x < 0 || object.body.bounds.x > this.widthInPixels || object.body.bounds.y < 0 || object.body.bounds.bottom > this.heightInPixels) {
return;
}
// What tiles do we need to check against?
this._tempTileX = this.game.math.snapToFloor(object.body.bounds.x, this.tileWidth) / this.tileWidth;
this._tempTileY = this.game.math.snapToFloor(object.body.bounds.y, this.tileHeight) / this.tileHeight;
this._tempTileW = (this.game.math.snapToCeil(object.body.bounds.width, this.tileWidth) + this.tileWidth) / this.tileWidth;
this._tempTileH = (this.game.math.snapToCeil(object.body.bounds.height, this.tileHeight) + this.tileHeight) / this.tileHeight;
// Loop through the tiles we've got and check overlaps accordingly (the results are stored in this._tempTileBlock)
this._tempBlockResults = [];
this.getTempBlock(this._tempTileX, this._tempTileY, this._tempTileW, this._tempTileH, true);
/*
for (var r = 0; r < this._tempTileBlock.length; r++)
{
if (this.game.world.physics.separateTile(object, this._tempTileBlock[r].x * this.tileWidth, this._tempTileBlock[r].y * this.tileHeight, this.tileWidth, this.tileHeight, this._tempTileBlock[r].tile.mass, this._tempTileBlock[r].tile.collideLeft, this._tempTileBlock[r].tile.collideRight, this._tempTileBlock[r].tile.collideUp, this._tempTileBlock[r].tile.collideDown, this._tempTileBlock[r].tile.separateX, this._tempTileBlock[r].tile.separateY) == true)
{
this._tempBlockResults.push({ x: this._tempTileBlock[r].x, y: this._tempTileBlock[r].y, tile: this._tempTileBlock[r].tile });
}
}
*/
return this._tempBlockResults;
};
TilemapLayer.prototype.getTempBlock = /**
* Get a tile block with its position and size. (This method does not return, it'll set result to _tempTileBlock)
* @param x {number} X position of block's left-top corner.
* @param y {number} Y position of block's left-top corner.
* @param width {number} Width of block.
* @param height {number} Height of block.
* @param collisionOnly {boolean} Whethor or not ONLY return tiles which will collide (its allowCollisions value is not Collision.NONE).
*/
function (x, y, width, height, collisionOnly) {
if (typeof collisionOnly === "undefined") { collisionOnly = false; }
if(x < 0) {
x = 0;
}
if(y < 0) {
y = 0;
}
if(width > this.widthInTiles) {
width = this.widthInTiles;
}
if(height > this.heightInTiles) {
height = this.heightInTiles;
}
this._tempTileBlock = [];
for(var ty = y; ty < y + height; ty++) {
for(var tx = x; tx < x + width; tx++) {
if(collisionOnly) {
// We only want to consider the tile for checking if you can actually collide with it
if(this.mapData[ty] && this.mapData[ty][tx] && this.parent.tiles[this.mapData[ty][tx]].allowCollisions != Phaser.Types.NONE) {
this._tempTileBlock.push({
x: tx,
y: ty,
tile: this.parent.tiles[this.mapData[ty][tx]]
});
}
} else {
if(this.mapData[ty] && this.mapData[ty][tx]) {
this._tempTileBlock.push({
x: tx,
y: ty,
tile: this.parent.tiles[this.mapData[ty][tx]]
});
}
}
}
}
};
TilemapLayer.prototype.getTileIndex = /**
* Get the tile index of specific position (in tiles).
* @param x {number} X position of the tile.
* @param y {number} Y position of the tile.
* @return {number} Index of the tile at that position. Return null if there isn't a tile there.
*/
function (x, y) {
if(y >= 0 && y < this.mapData.length) {
if(x >= 0 && x < this.mapData[y].length) {
return this.mapData[y][x];
}
}
return null;
};
TilemapLayer.prototype.addColumn = /**
* Add a column of tiles into the layer.
* @param column {string[]/number[]} An array of tile indexes to be added.
*/
function (column) {
var data = [];
for(var c = 0; c < column.length; c++) {
data[c] = parseInt(column[c]);
}
if(this.widthInTiles == 0) {
this.widthInTiles = data.length;
this.widthInPixels = this.widthInTiles * this.tileWidth;
}
this.mapData.push(data);
this.heightInTiles++;
this.heightInPixels += this.tileHeight;
};
TilemapLayer.prototype.updateBounds = /**
* Update boundsInTiles with widthInTiles and heightInTiles.
*/
function () {
this.boundsInTiles.setTo(0, 0, this.widthInTiles, this.heightInTiles);
};
TilemapLayer.prototype.parseTileOffsets = /**
* Parse tile offsets from map data.
* @return {number} length of tileOffsets array.
*/
function () {
this.tileOffsets = [];
var i = 0;
if(this.mapFormat == Phaser.Tilemap.FORMAT_TILED_JSON) {
// For some reason Tiled counts from 1 not 0
this.tileOffsets[0] = null;
i = 1;
}
for(var ty = this.tileMargin; ty < this.texture.height; ty += (this.tileHeight + this.tileSpacing)) {
for(var tx = this.tileMargin; tx < this.texture.width; tx += (this.tileWidth + this.tileSpacing)) {
this.tileOffsets[i] = {
x: tx,
y: ty
};
i++;
}
}
return this.tileOffsets.length;
};
return TilemapLayer;
})();
Phaser.TilemapLayer = TilemapLayer;
})(Phaser || (Phaser = {}));
/// Tile
.
*
* @param tilemap {Tilemap} the tilemap this tile belongs to.
* @param index {number} The index of this tile type in the core map data.
* @param width {number} Width of the tile.
* @param height number} Height of the tile.
*/
function Tile(game, tilemap, index, width, height) {
/**
* The virtual mass of the tile.
* @type {number}
*/
this.mass = 1.0;
/**
* Indicating collide with any object on the left.
* @type {boolean}
*/
this.collideLeft = false;
/**
* Indicating collide with any object on the right.
* @type {boolean}
*/
this.collideRight = false;
/**
* Indicating collide with any object on the top.
* @type {boolean}
*/
this.collideUp = false;
/**
* Indicating collide with any object on the bottom.
* @type {boolean}
*/
this.collideDown = false;
/**
* Enable separation at x-axis.
* @type {boolean}
*/
this.separateX = true;
/**
* Enable separation at y-axis.
* @type {boolean}
*/
this.separateY = true;
this._game = game;
this.tilemap = tilemap;
this.index = index;
this.width = width;
this.height = height;
this.allowCollisions = Phaser.Types.NONE;
}
Tile.prototype.destroy = /**
* Clean up memory.
*/
function () {
this.tilemap = null;
};
Tile.prototype.setCollision = /**
* Set collision configs.
* @param collision {number} Bit field of flags. (see Tile.allowCollision)
* @param resetCollisions {boolean} Reset collision flags before set.
* @param separateX {boolean} Enable seprate at x-axis.
* @param separateY {boolean} Enable seprate at y-axis.
*/
function (collision, resetCollisions, separateX, separateY) {
if(resetCollisions) {
this.resetCollision();
}
this.separateX = separateX;
this.separateY = separateY;
this.allowCollisions = collision;
if(collision & Phaser.Types.ANY) {
this.collideLeft = true;
this.collideRight = true;
this.collideUp = true;
this.collideDown = true;
return;
}
if(collision & Phaser.Types.LEFT || collision & Phaser.Types.WALL) {
this.collideLeft = true;
}
if(collision & Phaser.Types.RIGHT || collision & Phaser.Types.WALL) {
this.collideRight = true;
}
if(collision & Phaser.Types.UP || collision & Phaser.Types.CEILING) {
this.collideUp = true;
}
if(collision & Phaser.Types.DOWN || collision & Phaser.Types.CEILING) {
this.collideDown = true;
}
};
Tile.prototype.resetCollision = /**
* Reset collision status flags.
*/
function () {
this.allowCollisions = Phaser.Types.NONE;
this.collideLeft = false;
this.collideRight = false;
this.collideUp = false;
this.collideDown = false;
};
Tile.prototype.toString = /**
* Returns a string representation of this object.
* @method toString
* @return {string} a string representation of the object.
**/
function () {
return "[{Tiled (index=" + this.index + " collisions=" + this.allowCollisions + " width=" + this.width + " height=" + this.height + ")}]";
};
return Tile;
})();
Phaser.Tile = Tile;
})(Phaser || (Phaser = {}));
/// Tilemap
.
*
* @param game {Phaser.Game} Current game instance.
* @param key {string} Asset key for this map.
* @param mapData {string} Data of this map. (a big 2d array, normally in csv)
* @param format {number} Format of this map data, available: Tilemap.FORMAT_CSV or Tilemap.FORMAT_TILED_JSON.
* @param resizeWorld {boolean} Resize the world bound automatically based on this tilemap?
* @param tileWidth {number} Width of tiles in this map.
* @param tileHeight {number} Height of tiles in this map.
*/
function Tilemap(game, key, mapData, format, resizeWorld, tileWidth, tileHeight) {
if (typeof resizeWorld === "undefined") { resizeWorld = true; }
if (typeof tileWidth === "undefined") { tileWidth = 0; }
if (typeof tileHeight === "undefined") { tileHeight = 0; }
/**
* The Events component
*/
//public events: Phaser.Components.Sprite.Events;
/**
* z order value of the object.
*/
this.z = -1;
/**
* Render iteration counter
*/
this.renderOrderID = 0;
/**
* Tilemap collision callback.
* @type {function}
*/
this.collisionCallback = null;
this.game = game;
this.type = Phaser.Types.TILEMAP;
this.exists = true;
this.active = true;
this.visible = true;
this.alive = true;
this.z = -1;
this.group = null;
this.name = '';
this.texture = new Phaser.Display.Texture(this);
this.transform = new Phaser.Components.TransformManager(this);
this.tiles = [];
this.layers = [];
this.mapFormat = format;
switch(format) {
case Tilemap.FORMAT_CSV:
this.parseCSV(game.cache.getText(mapData), key, tileWidth, tileHeight);
break;
case Tilemap.FORMAT_TILED_JSON:
this.parseTiledJSON(game.cache.getText(mapData), key);
break;
}
if(this.currentLayer && resizeWorld) {
this.game.world.setSize(this.currentLayer.widthInPixels, this.currentLayer.heightInPixels, true);
}
}
Tilemap.FORMAT_CSV = 0;
Tilemap.FORMAT_TILED_JSON = 1;
Tilemap.prototype.preUpdate = /**
* Inherited methods for overriding.
*/
function () {
};
Tilemap.prototype.update = function () {
};
Tilemap.prototype.postUpdate = function () {
};
Tilemap.prototype.destroy = function () {
};
Tilemap.prototype.parseCSV = /**
* Parset csv map data and generate tiles.
* @param data {string} CSV map data.
* @param key {string} Asset key for tileset image.
* @param tileWidth {number} Width of its tile.
* @param tileHeight {number} Height of its tile.
*/
function (data, key, tileWidth, tileHeight) {
var layer = new Phaser.TilemapLayer(this.game, this, key, Tilemap.FORMAT_CSV, 'TileLayerCSV' + this.layers.length.toString(), tileWidth, tileHeight);
// Trim any rogue whitespace from the data
data = data.trim();
var rows = data.split("\n");
for(var i = 0; i < rows.length; i++) {
var column = rows[i].split(",");
if(column.length > 0) {
layer.addColumn(column);
}
}
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
this.generateTiles(tileQuantity);
};
Tilemap.prototype.parseTiledJSON = /**
* Parse JSON map data and generate tiles.
* @param data {string} JSON map data.
* @param key {string} Asset key for tileset image.
*/
function (data, key) {
// Trim any rogue whitespace from the data
data = data.trim();
var json = JSON.parse(data);
for(var i = 0; i < json.layers.length; i++) {
var layer = new Phaser.TilemapLayer(this.game, this, key, Tilemap.FORMAT_TILED_JSON, json.layers[i].name, json.tilewidth, json.tileheight);
// Check it's a data layer
if(!json.layers[i].data) {
continue;
}
layer.alpha = json.layers[i].opacity;
layer.visible = json.layers[i].visible;
layer.tileMargin = json.tilesets[0].margin;
layer.tileSpacing = json.tilesets[0].spacing;
var c = 0;
var row;
for(var t = 0; t < json.layers[i].data.length; t++) {
if(c == 0) {
row = [];
}
row.push(json.layers[i].data[t]);
c++;
if(c == json.layers[i].width) {
layer.addColumn(row);
c = 0;
}
}
layer.updateBounds();
var tileQuantity = layer.parseTileOffsets();
this.currentLayer = layer;
this.collisionLayer = layer;
this.layers.push(layer);
}
this.generateTiles(tileQuantity);
};
Tilemap.prototype.generateTiles = /**
* Create tiles of given quantity.
* @param qty {number} Quentity of tiles to be generated.
*/
function (qty) {
for(var i = 0; i < qty; i++) {
this.tiles.push(new Phaser.Tile(this.game, this, i, this.currentLayer.tileWidth, this.currentLayer.tileHeight));
}
};
Object.defineProperty(Tilemap.prototype, "widthInPixels", {
get: function () {
return this.currentLayer.widthInPixels;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Tilemap.prototype, "heightInPixels", {
get: function () {
return this.currentLayer.heightInPixels;
},
enumerable: true,
configurable: true
});
Tilemap.prototype.setCollisionCallback = // Tile Collision
/**
* Set callback to be called when this tilemap collides.
* @param context {object} Callback will be called with this context.
* @param callback {function} Callback function.
*/
function (context, callback) {
this.collisionCallbackContext = context;
this.collisionCallback = callback;
};
Tilemap.prototype.setCollisionRange = /**
* Set collision configs of tiles in a range index.
* @param start {number} First index of tiles.
* @param end {number} Last index of tiles.
* @param collision {number} Bit field of flags. (see Tile.allowCollision)
* @param resetCollisions {boolean} Reset collision flags before set.
* @param separateX {boolean} Enable seprate at x-axis.
* @param separateY {boolean} Enable seprate at y-axis.
*/
function (start, end, collision, resetCollisions, separateX, separateY) {
if (typeof collision === "undefined") { collision = Phaser.Types.ANY; }
if (typeof resetCollisions === "undefined") { resetCollisions = false; }
if (typeof separateX === "undefined") { separateX = true; }
if (typeof separateY === "undefined") { separateY = true; }
for(var i = start; i < end; i++) {
this.tiles[i].setCollision(collision, resetCollisions, separateX, separateY);
}
};
Tilemap.prototype.setCollisionByIndex = /**
* Set collision configs of tiles with given index.
* @param values {number[]} Index array which contains all tile indexes. The tiles with those indexes will be setup with rest parameters.
* @param collision {number} Bit field of flags. (see Tile.allowCollision)
* @param resetCollisions {boolean} Reset collision flags before set.
* @param separateX {boolean} Enable seprate at x-axis.
* @param separateY {boolean} Enable seprate at y-axis.
*/
function (values, collision, resetCollisions, separateX, separateY) {
if (typeof collision === "undefined") { collision = Phaser.Types.ANY; }
if (typeof resetCollisions === "undefined") { resetCollisions = false; }
if (typeof separateX === "undefined") { separateX = true; }
if (typeof separateY === "undefined") { separateY = true; }
for(var i = 0; i < values.length; i++) {
this.tiles[values[i]].setCollision(collision, resetCollisions, separateX, separateY);
}
};
Tilemap.prototype.getTileByIndex = // Tile Management
/**
* Get the tile by its index.
* @param value {number} Index of the tile you want to get.
* @return {Tile} The tile with given index.
*/
function (value) {
if(this.tiles[value]) {
return this.tiles[value];
}
return null;
};
Tilemap.prototype.getTile = /**
* Get the tile located at specific position and layer.
* @param x {number} X position of this tile located.
* @param y {number} Y position of this tile located.
* @param [layer] {number} layer of this tile located.
* @return {Tile} The tile with specific properties.
*/
function (x, y, layer) {
if (typeof layer === "undefined") { layer = 0; }
return this.tiles[this.layers[layer].getTileIndex(x, y)];
};
Tilemap.prototype.getTileFromWorldXY = /**
* Get the tile located at specific position (in world coordinate) and layer. (thus you give a position of a point which is within the tile)
* @param x {number} X position of the point in target tile.
* @param x {number} Y position of the point in target tile.
* @param [layer] {number} layer of this tile located.
* @return {Tile} The tile with specific properties.
*/
function (x, y, layer) {
if (typeof layer === "undefined") { layer = 0; }
return this.tiles[this.layers[layer].getTileFromWorldXY(x, y)];
};
Tilemap.prototype.getTileFromInputXY = /**
* Gets the tile underneath the Input.x/y position
* @param layer The layer to check, defaults to 0
* @returns {Tile}
*/
function (layer) {
if (typeof layer === "undefined") { layer = 0; }
return this.tiles[this.layers[layer].getTileFromWorldXY(this.game.input.getWorldX(), this.game.input.getWorldY())];
};
Tilemap.prototype.getTileOverlaps = /**
* Get tiles overlaps the given object.
* @param object {GameObject} Tiles you want to get that overlaps this.
* @return {array} Array with tiles information. (Each contains x, y and the tile.)
*/
function (object) {
return this.currentLayer.getTileOverlaps(object);
};
Tilemap.prototype.collide = // COLLIDE
/**
* Check whether this tilemap collides with the given game object or group of objects.
* @param objectOrGroup {function} Target object of group you want to check.
* @param callback {function} This is called if objectOrGroup collides the tilemap.
* @param context {object} Callback will be called with this context.
* @return {boolean} Return true if this collides with given object, otherwise return false.
*/
function (objectOrGroup, callback, context) {
if (typeof objectOrGroup === "undefined") { objectOrGroup = null; }
if (typeof callback === "undefined") { callback = null; }
if (typeof context === "undefined") { context = null; }
if(callback !== null && context !== null) {
this.collisionCallback = callback;
this.collisionCallbackContext = context;
}
if(objectOrGroup == null) {
objectOrGroup = this.game.world.group;
}
// Group?
if(objectOrGroup.isGroup == false) {
this.collideGameObject(objectOrGroup);
} else {
objectOrGroup.forEachAlive(this, this.collideGameObject, true);
}
};
Tilemap.prototype.collideGameObject = /**
* Check whether this tilemap collides with the given game object.
* @param object {GameObject} Target object you want to check.
* @return {boolean} Return true if this collides with given object, otherwise return false.
*/
function (object) {
if(object.body.type == Phaser.Types.BODY_DYNAMIC && object.exists == true && object.body.allowCollisions != Phaser.Types.NONE) {
this._tempCollisionData = this.collisionLayer.getTileOverlaps(object);
if(this.collisionCallback !== null && this._tempCollisionData.length > 0) {
this.collisionCallback.call(this.collisionCallbackContext, object, this._tempCollisionData);
}
return true;
} else {
return false;
}
};
Tilemap.prototype.putTile = /**
* Set a tile to a specific layer.
* @param x {number} X position of this tile.
* @param y {number} Y position of this tile.
* @param index {number} The index of this tile type in the core map data.
* @param [layer] {number} which layer you want to set the tile to.
*/
function (x, y, index, layer) {
if (typeof layer === "undefined") { layer = 0; }
this.layers[layer].putTile(x, y, index);
};
return Tilemap;
})();
Phaser.Tilemap = Tilemap;
// Set current layer
// Set layer order?
// Delete tiles of certain type
// Erase tiles
})(Phaser || (Phaser = {}));
/// SoundManager
.
*/
function SoundManager(game) {
this.usingWebAudio = false;
this.usingAudioTag = false;
this.noAudio = false;
/**
* Reference to AudioContext instance.
*/
this.context = null;
this._muted = false;
this.touchLocked = false;
this._unlockSource = null;
this.onSoundDecode = new Phaser.Signal();
this.game = game;
this._volume = 1;
this._muted = false;
this._sounds = [];
if(this.game.device.iOS && this.game.device.webAudio == false) {
this.channels = 1;
}
if(this.game.device.iOS || (window['PhaserGlobal'] && window['PhaserGlobal'].fakeiOSTouchLock)) {
//console.log('iOS Touch Locked');
this.game.input.touch.callbackContext = this;
this.game.input.touch.touchStartCallback = this.unlock;
this.game.input.mouse.callbackContext = this;
this.game.input.mouse.mouseDownCallback = this.unlock;
this.touchLocked = true;
} else {
// What about iOS5?
this.touchLocked = false;
}
if(window['PhaserGlobal']) {
// Check to see if all audio playback is disabled (i.e. handled by a 3rd party class)
if(window['PhaserGlobal'].disableAudio == true) {
this.usingWebAudio = false;
this.noAudio = true;
return;
}
// Check if the Web Audio API is disabled (for testing Audio Tag playback during development)
if(window['PhaserGlobal'].disableWebAudio == true) {
this.usingWebAudio = false;
this.usingAudioTag = true;
this.noAudio = false;
return;
}
}
this.usingWebAudio = true;
this.noAudio = false;
if(!!window['AudioContext']) {
this.context = new window['AudioContext']();
} else if(!!window['webkitAudioContext']) {
this.context = new window['webkitAudioContext']();
} else if(!!window['Audio']) {
this.usingWebAudio = false;
this.usingAudioTag = true;
} else {
this.usingWebAudio = false;
this.noAudio = true;
}
if(this.context !== null) {
if(typeof this.context.createGain === 'undefined') {
this.masterGain = this.context.createGainNode();
} else {
this.masterGain = this.context.createGain();
}
this.masterGain.gain.value = 1;
this.masterGain.connect(this.context.destination);
}
}
SoundManager.prototype.unlock = function () {
if(this.touchLocked == false) {
return;
}
//console.log('SoundManager touch unlocked');
if(this.game.device.webAudio && (window['PhaserGlobal'] && window['PhaserGlobal'].disableWebAudio == false)) {
//console.log('create empty buffer');
// Create empty buffer and play it
var buffer = this.context.createBuffer(1, 1, 22050);
this._unlockSource = this.context.createBufferSource();
this._unlockSource.buffer = buffer;
this._unlockSource.connect(this.context.destination);
this._unlockSource.noteOn(0);
} else {
// Create an Audio tag?
//console.log('create audio tag');
this.touchLocked = false;
this._unlockSource = null;
this.game.input.touch.callbackContext = null;
this.game.input.touch.touchStartCallback = null;
this.game.input.mouse.callbackContext = null;
this.game.input.mouse.mouseDownCallback = null;
}
};
Object.defineProperty(SoundManager.prototype, "mute", {
get: /**
* A global audio mute toggle.
*/
function () {
return this._muted;
},
set: function (value) {
console.log('SoundManager mute', value);
if(value) {
if(this._muted) {
return;
}
this._muted = true;
if(this.usingWebAudio) {
this._muteVolume = this.masterGain.gain.value;
this.masterGain.gain.value = 0;
}
// Loop through sounds
for(var i = 0; i < this._sounds.length; i++) {
if(this._sounds[i].usingAudioTag) {
this._sounds[i].mute = true;
}
}
} else {
if(this._muted == false) {
return;
}
this._muted = false;
if(this.usingWebAudio) {
this.masterGain.gain.value = this._muteVolume;
}
// Loop through sounds
for(var i = 0; i < this._sounds.length; i++) {
if(this._sounds[i].usingAudioTag) {
this._sounds[i].mute = false;
}
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(SoundManager.prototype, "volume", {
get: function () {
if(this.usingWebAudio) {
return this.masterGain.gain.value;
} else {
return this._volume;
}
},
set: /**
* The global audio volume. A value between 0 (silence) and 1 (full volume)
*/
function (value) {
value = this.game.math.clamp(value, 1, 0);
this._volume = value;
if(this.usingWebAudio) {
this.masterGain.gain.value = value;
}
// Loop through the sound cache and change the volume of all html audio tags
for(var i = 0; i < this._sounds.length; i++) {
if(this._sounds[i].usingAudioTag) {
this._sounds[i].volume = this._sounds[i].volume * value;
}
}
},
enumerable: true,
configurable: true
});
SoundManager.prototype.stopAll = function () {
for(var i = 0; i < this._sounds.length; i++) {
if(this._sounds[i]) {
this._sounds[i].stop();
}
}
};
SoundManager.prototype.pauseAll = function () {
for(var i = 0; i < this._sounds.length; i++) {
if(this._sounds[i]) {
this._sounds[i].pause();
}
}
};
SoundManager.prototype.resumeAll = function () {
for(var i = 0; i < this._sounds.length; i++) {
if(this._sounds[i]) {
this._sounds[i].resume();
}
}
};
SoundManager.prototype.decode = /**
* Decode a sound with its assets key.
* @param key {string} Assets key of the sound to be decoded.
* @param [sound] {Sound} its bufer will be set to decoded data.
*/
function (key, sound) {
if (typeof sound === "undefined") { sound = null; }
var soundData = this.game.cache.getSoundData(key);
if(soundData) {
if(this.game.cache.isSoundDecoded(key) === false) {
this.game.cache.updateSound(key, 'isDecoding', true);
var that = this;
this.context.decodeAudioData(soundData, function (buffer) {
that.game.cache.decodedSound(key, buffer);
if(sound) {
that.onSoundDecode.dispatch(sound);
}
});
}
}
};
SoundManager.prototype.update = function () {
if(this.touchLocked) {
if(this.game.device.webAudio && this._unlockSource !== null) {
if((this._unlockSource.playbackState === this._unlockSource.PLAYING_STATE || this._unlockSource.playbackState === this._unlockSource.FINISHED_STATE)) {
this.touchLocked = false;
this._unlockSource = null;
this.game.input.touch.callbackContext = null;
this.game.input.touch.touchStartCallback = null;
}
}
}
for(var i = 0; i < this._sounds.length; i++) {
this._sounds[i].update();
}
};
SoundManager.prototype.add = function (key, volume, loop) {
if (typeof volume === "undefined") { volume = 1; }
if (typeof loop === "undefined") { loop = false; }
var sound = new Phaser.Sound(this.game, key, volume, loop);
this._sounds.push(sound);
return sound;
};
return SoundManager;
})();
Phaser.SoundManager = SoundManager;
})(Phaser || (Phaser = {}));
/**
* Phaser
*
* v1.0.0 - August 12th 2013
*
* A feature-packed 2D canvas game framework born from the firey pits of Flixel and Kiwi.
*
* Richard Davey (@photonstorm)
*
* Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from both which Phaser
* and my love of game development took a lot of inspiration.
*
* "If you want your children to be intelligent, read them fairy tales."
* "If you want them to be more intelligent, read them more fairy tales."
* -- Albert Einstein
*/
var Phaser;
(function (Phaser) {
Phaser.VERSION = 'Phaser version 1.0.0';
Phaser.GAMES = [];
})(Phaser || (Phaser = {}));
var Phaser;
(function (Phaser) {
/// BootScreen
with specific width and height.
*
* @param width {number} Screen canvas width.
* @param height {number} Screen canvas height.
*/
function BootScreen(game) {
/**
* Engine logo image data.
*/
this._logoData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAAAZCAYAAADdYmvFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAstJREFUeNrsWlFuwjAMbavdZGcAcRm4AXzvCPuGG8BlEJxhZ+l4TJ48z3actGGthqUI1MaO/V6cmIT2/fW10eTt46NvKshtvDZlG31yfOL9a/ldU6x4IZ0GQs0gS217enMkJYr5ixXkYrFoVqtV1kDn8/n+KfXw/Hq9Nin7h8MhScB2u3Xtav2ivsNWrh7XLcWMYqA4eUZ1kj0MAifHJEeKFojWzyIH+rL/0Cwif2AX9nN1oQOgrTg8XcTFx+ScdEOJ4WBxXQ1EjRyrn0cOzzQLzFyQSQcgw/5Qkkr0JVEQpNIdhL4vm4DL5fLulNTHcy6Uxl4/6iMLiePx2KzX6/v30+n0aynUlrnSeNq2/VN9bgM4dFPdNPmsJnIg/PuQbJmLdFN3UNu0SzbyJ0GOWJVWZE/QMkY+owrqXxGEdZA37BVyX6lJTipT6J1lf7fbqc+xh8nYeIvikatP+PGW0nEJ4jOydHYOIcfKnmgWoZDQSIIeio4Sf1IthYWskCO4vqQ6lFYjl8tl9L1H67PZbMz3VO3t93uVXHofmUjReLyMwHi5eCb3ICwJj5ZU9nCg+SzUgPYyif+2epTk4pkkyDp+eXTlZu2BkUybEkklePZfK9lPuTnc07vbmt1bYulHBeNQgx18SsH4ni/cV2rSLtqNDNUH2JQ2SsXS57Y9PHlfumkwCdICt5rnkNdPjpMiIEWgRlAJSdF4SvCQMWj+VyfI0h8D/EgWSYKiJKXi8VrOhJUxaFiFCOKKUJAtR78k9eX4USLHXqLGXOIiWUT4Vj9JiP4W0io3VDz8AJXblNWQrOimLjIGy/9uLICH6mrVmFbxEFHauzmc0fGJJmPg/v+6D0oB7N2bj0FsNHtSWTQniWTR931QlHXvasDTHXLjqY0/1/8hSDxACD+lAGH8dKQbQk5N3TFtzDmLWutvV0+pL5FVoHvCNG35FGAAayS4KUoKC9QAAAAASUVORK5CYII=";
/**
* Background gradient effect color 1.
*/
this._color1 = {
r: 20,
g: 20,
b: 20
};
/**
* Background gradient effect color 2.
*/
this._color2 = {
r: 200,
g: 200,
b: 200
};
/**
* Fade effect tween.
* @type {Phaser.Tween}
*/
this._fade = null;
this._game = game;
this._logo = new Image();
this._logo.src = this._logoData;
}
BootScreen.prototype.update = /**
* Update color and fade.
*/
function () {
if(this._fade == null) {
this.colorCycle();
}
this._color1.r = Math.round(this._color1.r);
this._color1.g = Math.round(this._color1.g);
this._color1.b = Math.round(this._color1.b);
this._color2.r = Math.round(this._color2.r);
this._color2.g = Math.round(this._color2.g);
this._color2.b = Math.round(this._color2.b);
};
BootScreen.prototype.render = /**
* Render BootScreen.
*/
function () {
var grd = this._game.stage.context.createLinearGradient(0, 0, 0, this._game.stage.height);
grd.addColorStop(0, 'rgb(' + this._color1.r + ', ' + this._color1.g + ', ' + this._color1.b + ')');
grd.addColorStop(0.5, 'rgb(' + this._color2.r + ', ' + this._color2.g + ', ' + this._color2.b + ')');
grd.addColorStop(1, 'rgb(' + this._color1.r + ', ' + this._color1.g + ', ' + this._color1.b + ')');
this._game.stage.context.fillStyle = grd;
this._game.stage.context.fillRect(0, 0, this._game.stage.width, this._game.stage.height);
this._game.stage.context.shadowOffsetX = 0;
this._game.stage.context.shadowOffsetY = 0;
if(this._logo) {
this._game.stage.context.drawImage(this._logo, 32, 32);
}
this._game.stage.context.shadowColor = 'rgb(0,0,0)';
this._game.stage.context.shadowOffsetX = 1;
this._game.stage.context.shadowOffsetY = 1;
this._game.stage.context.shadowBlur = 0;
this._game.stage.context.fillStyle = 'rgb(255,255,255)';
this._game.stage.context.font = 'bold 18px Arial';
this._game.stage.context.textBaseline = 'top';
this._game.stage.context.fillText(Phaser.VERSION, 32, 64 + 32);
this._game.stage.context.fillText('Game Size: ' + this._game.stage.width + ' x ' + this._game.stage.height, 32, 64 + 64);
this._game.stage.context.fillText('www.photonstorm.com', 32, 64 + 96);
this._game.stage.context.font = '16px Arial';
this._game.stage.context.fillText('You are seeing this screen because you didn\'t specify any default', 32, 64 + 160);
this._game.stage.context.fillText('functions in the Game constructor or use Game.switchState()', 32, 64 + 184);
};
BootScreen.prototype.colorCycle = /**
* Start color fading cycle.
*/
function () {
this._fade = this._game.add.tween(this._color2);
this._fade.to({
r: Math.random() * 250,
g: Math.random() * 250,
b: Math.random() * 250
}, 3000, Phaser.Easing.Linear.None);
this._fade.onComplete.add(this.colorCycle, this);
this._fade.start();
};
return BootScreen;
})();
Phaser.BootScreen = BootScreen;
})(Phaser || (Phaser = {}));
/// PauseScreen
with specific width and height.
*
* @param width {number} Screen canvas width.
* @param height {number} Screen canvas height.
*/
function PauseScreen(game, width, height) {
this._game = game;
this._canvas = document.createElement('canvas');
this._canvas.width = width;
this._canvas.height = height;
this._context = this._canvas.getContext('2d');
}
PauseScreen.prototype.onPaused = /**
* Called when the game enters pause mode.
*/
function () {
// Take a grab of the current canvas to our temporary one
this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
this._context.drawImage(this._game.stage.canvas, 0, 0);
this._color = {
r: 255,
g: 255,
b: 255
};
this.fadeOut();
};
PauseScreen.prototype.onResume = /**
* Called when the game resume from pause mode.
*/
function () {
this._fade.stop();
this._game.tweens.remove(this._fade);
};
PauseScreen.prototype.update = /**
* Update background color.
*/
function () {
this._color.r = Math.round(this._color.r);
this._color.g = Math.round(this._color.g);
this._color.b = Math.round(this._color.b);
};
PauseScreen.prototype.render = /**
* Render PauseScreen.
*/
function () {
this._game.stage.context.drawImage(this._canvas, 0, 0);
this._game.stage.context.fillStyle = 'rgba(0, 0, 0, 0.4)';
this._game.stage.context.fillRect(0, 0, this._game.stage.width, this._game.stage.height);
// Draw a 'play' arrow
var arrowWidth = Math.round(this._game.stage.width / 2);
var arrowHeight = Math.round(this._game.stage.height / 2);
var sx = this._game.stage.centerX - arrowWidth / 2;
var sy = this._game.stage.centerY - arrowHeight / 2;
this._game.stage.context.beginPath();
this._game.stage.context.moveTo(sx, sy);
this._game.stage.context.lineTo(sx, sy + arrowHeight);
this._game.stage.context.lineTo(sx + arrowWidth, this._game.stage.centerY);
this._game.stage.context.fillStyle = 'rgba(' + this._color.r + ', ' + this._color.g + ', ' + this._color.b + ', 0.8)';
this._game.stage.context.fill();
this._game.stage.context.closePath();
};
PauseScreen.prototype.fadeOut = /**
* Start fadeOut effect.
*/
function () {
this._fade = this._game.add.tween(this._color);
this._fade.to({
r: 50,
g: 50,
b: 50
}, 1000, Phaser.Easing.Linear.None);
this._fade.onComplete.add(this.fadeIn, this);
this._fade.start();
};
PauseScreen.prototype.fadeIn = /**
* Start fadeIn effect.
*/
function () {
this._fade = this._game.add.tween(this._color);
this._fade.to({
r: 255,
g: 255,
b: 255
}, 1000, Phaser.Easing.Linear.None);
this._fade.onComplete.add(this.fadeOut, this);
this._fade.start();
};
return PauseScreen;
})();
Phaser.PauseScreen = PauseScreen;
})(Phaser || (Phaser = {}));
/// OrientationScreen
with specific width and height.
*
* @param width {number} Screen canvas width.
* @param height {number} Screen canvas height.
*/
function OrientationScreen(game) {
this._showOnLandscape = false;
this._showOnPortrait = false;
this.game = game;
}
OrientationScreen.prototype.enable = function (onLandscape, onPortrait, imageKey) {
this._showOnLandscape = onLandscape;
this._showOnPortrait = onPortrait;
this.landscapeImage = this.game.cache.getImage(imageKey);
this.portraitImage = this.game.cache.getImage(imageKey);
};
OrientationScreen.prototype.update = /**
* Update
*/
function () {
};
OrientationScreen.prototype.render = /**
* Render
*/
function () {
if(this._showOnLandscape) {
this.game.stage.context.drawImage(this.landscapeImage, 0, 0, this.landscapeImage.width, this.landscapeImage.height, 0, 0, this.game.stage.width, this.game.stage.height);
} else if(this._showOnPortrait) {
this.game.stage.context.drawImage(this.portraitImage, 0, 0, this.portraitImage.width, this.portraitImage.height, 0, 0, this.game.stage.width, this.game.stage.height);
}
};
return OrientationScreen;
})();
Phaser.OrientationScreen = OrientationScreen;
})(Phaser || (Phaser = {}));
/// Stage
with specific width and height.
*
* @param parent {number} ID of parent DOM element.
* @param width {number} Width of the stage.
* @param height {number} Height of the stage.
*/
function Stage(game, parent, width, height) {
var _this = this;
/**
* Background color of the stage (defaults to black). Set via the public backgroundColor property.
* @type {string}
*/
this._backgroundColor = 'rgb(0,0,0)';
/**
* Clear the whole stage every frame? (Default to true)
* @type {boolean}
*/
this.clear = true;
/**
* Do not use pause screen when game is paused?
* (Default to false, aka always use PauseScreen)
* @type {boolean}
*/
this.disablePauseScreen = false;
/**
* Do not use boot screen when engine starts?
* (Default to false, aka always use BootScreen)
* @type {boolean}
*/
this.disableBootScreen = false;
/**
* If set to true the game will never pause when the browser or browser tab loses focuses
* @type {boolean}
*/
this.disableVisibilityChange = false;
/**
* An optional 'fix' for the horrendous Android stock browser bug
* https://code.google.com/p/android/issues/detail?id=39247
* @type {boolean}
*/
this.patchAndroidClearRectBug = false;
this._game = game;
this.canvas = document.createElement('canvas');
this.canvas.width = width;
this.canvas.height = height;
if((parent !== '' || parent !== null) && document.getElementById(parent)) {
document.getElementById(parent).appendChild(this.canvas);
document.getElementById(parent).style.overflow = 'hidden';
} else {
document.body.appendChild(this.canvas);
}
// Consume default actions on the canvas
this.canvas.style.msTouchAction = 'none';
this.canvas.style['ms-touch-action'] = 'none';
this.canvas.style['touch-action'] = 'none';
this.canvas.style.backgroundColor = 'rgb(0,0,0)';
this.canvas.oncontextmenu = function (event) {
event.preventDefault();
};
this.context = this.canvas.getContext('2d');
this.css3 = new Phaser.Display.CSS3Filters(this.canvas);
this.scaleMode = Phaser.StageScaleMode.NO_SCALE;
this.scale = new Phaser.StageScaleMode(this._game, width, height);
this.getOffset(this.canvas);
this.bounds = new Phaser.Rectangle(this.offset.x, this.offset.y, width, height);
this.aspectRatio = width / height;
document.addEventListener('visibilitychange', function (event) {
return _this.visibilityChange(event);
}, false);
document.addEventListener('webkitvisibilitychange', function (event) {
return _this.visibilityChange(event);
}, false);
document.addEventListener('pagehide', function (event) {
return _this.visibilityChange(event);
}, false);
document.addEventListener('pageshow', function (event) {
return _this.visibilityChange(event);
}, false);
window.onblur = function (event) {
return _this.visibilityChange(event);
};
window.onfocus = function (event) {
return _this.visibilityChange(event);
};
}
Stage.prototype.boot = /**
* Stage boot
*/
function () {
this.bootScreen = new Phaser.BootScreen(this._game);
this.pauseScreen = new Phaser.PauseScreen(this._game, this.width, this.height);
this.orientationScreen = new Phaser.OrientationScreen(this._game);
this.scale.setScreenSize(true);
};
Stage.prototype.update = /**
* Update stage for rendering. This will handle scaling, clearing
* and PauseScreen/BootScreen updating and rendering.
*/
function () {
this.scale.update();
if(this.clear || (this._game.paused && this.disablePauseScreen == false)) {
if(this.patchAndroidClearRectBug) {
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();
this.orientationScreen.render();
return;
}
if(this._game.isRunning == false && this.disableBootScreen == false) {
this.bootScreen.update();
this.bootScreen.render();
}
if(this._game.paused && this.disablePauseScreen == false) {
this.pauseScreen.update();
this.pauseScreen.render();
}
};
Stage.prototype.visibilityChange = /**
* This method is called when the canvas elements visibility is changed.
*/
function (event) {
if(this.disableVisibilityChange) {
return;
}
if(event.type == 'pagehide' || event.type == 'blur' || document['hidden'] == true || document['webkitHidden'] == true) {
if(this._game.paused == false) {
this.pauseGame();
}
} else {
if(this._game.paused == true) {
this.resumeGame();
}
}
};
Stage.prototype.enableOrientationCheck = function (forceLandscape, forcePortrait, imageKey) {
if (typeof imageKey === "undefined") { imageKey = ''; }
this.scale.forceLandscape = forceLandscape;
this.scale.forcePortrait = forcePortrait;
this.orientationScreen.enable(forceLandscape, forcePortrait, imageKey);
if(forceLandscape || forcePortrait) {
if((this.scale.isLandscape && forcePortrait) || (this.scale.isPortrait && forceLandscape)) {
// They are in the wrong orientation right now
this._game.paused = true;
this.scale.incorrectOrientation = true;
} else {
this.scale.incorrectOrientation = false;
}
}
};
Stage.prototype.setImageRenderingCrisp = function () {
this.canvas.style['image-rendering'] = 'crisp-edges';
this.canvas.style['image-rendering'] = '-moz-crisp-edges';
this.canvas.style['image-rendering'] = '-webkit-optimize-contrast';
this.canvas.style['-ms-interpolation-mode'] = 'nearest-neighbor';
};
Stage.prototype.pauseGame = function () {
if(this.disablePauseScreen == false && this.pauseScreen) {
this.pauseScreen.onPaused();
}
this.saveCanvasValues();
this._game.paused = true;
};
Stage.prototype.resumeGame = function () {
if(this.disablePauseScreen == false && this.pauseScreen) {
this.pauseScreen.onResume();
}
this.restoreCanvasValues();
this._game.paused = false;
};
Stage.prototype.getOffset = /**
* Get the DOM offset values of the given element
*/
function (element, populateOffset) {
if (typeof populateOffset === "undefined") { populateOffset = true; }
var box = element.getBoundingClientRect();
var clientTop = element.clientTop || document.body.clientTop || 0;
var clientLeft = element.clientLeft || document.body.clientLeft || 0;
var scrollTop = window.pageYOffset || element.scrollTop || document.body.scrollTop;
var scrollLeft = window.pageXOffset || element.scrollLeft || document.body.scrollLeft;
if(populateOffset) {
this.offset = new Phaser.Point(box.left + scrollLeft - clientLeft, box.top + scrollTop - clientTop);
return this.offset;
} else {
return new Phaser.Point(box.left + scrollLeft - clientLeft, box.top + scrollTop - clientTop);
}
};
Stage.prototype.saveCanvasValues = /**
* Save current canvas properties (strokeStyle, lineWidth and fillStyle) for later using.
*/
function () {
this.strokeStyle = this.context.strokeStyle;
this.lineWidth = this.context.lineWidth;
this.fillStyle = this.context.fillStyle;
};
Stage.prototype.restoreCanvasValues = /**
* Restore current canvas values (strokeStyle, lineWidth and fillStyle) with saved values.
*/
function () {
this.context.strokeStyle = this.strokeStyle;
this.context.lineWidth = this.lineWidth;
this.context.fillStyle = this.fillStyle;
if(this.patchAndroidClearRectBug) {
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);
}
};
Object.defineProperty(Stage.prototype, "backgroundColor", {
get: function () {
return this._backgroundColor;
},
set: function (color) {
this.canvas.style.backgroundColor = color;
this._backgroundColor = color;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "x", {
get: function () {
return this.bounds.x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "y", {
get: function () {
return this.bounds.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "width", {
get: function () {
return this.bounds.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "height", {
get: function () {
return this.bounds.height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "centerX", {
get: function () {
return this.bounds.halfWidth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "centerY", {
get: function () {
return this.bounds.halfHeight;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "randomX", {
get: function () {
return Math.round(Math.random() * this.bounds.width);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "randomY", {
get: function () {
return Math.round(Math.random() * this.bounds.height);
},
enumerable: true,
configurable: true
});
return Stage;
})();
Phaser.Stage = Stage;
})(Phaser || (Phaser = {}));
/// Time
.
*
* @param game {Phaser.Game} Current game instance.
*/
function TimeManager(game) {
/**
* Time scale factor.
* Set it to 0.5 for slow motion, to 2.0 makes game twice faster.
* @type {number}
*/
this.timeScale = 1.0;
/**
* Elapsed since last frame.
* @type {number}
*/
this.elapsed = 0;
/**
* Game time counter.
* @property time
* @type {number}
*/
this.time = 0;
/**
* Time of current frame.
* @property now
* @type {number}
*/
this.now = 0;
/**
* Elapsed time since last frame.
* @property delta
* @type {number}
*/
this.delta = 0;
/**
* Frames per second.
* @type {number}
*/
this.fps = 0;
/**
* Minimal fps.
* @type {number}
*/
this.fpsMin = 1000;
/**
* Maximal fps.
* @type {number}
*/
this.fpsMax = 0;
/**
* Mininal duration between 2 frames.
* @type {number}
*/
this.msMin = 1000;
/**
* Maximal duration between 2 frames.
* @type {number}
*/
this.msMax = 0;
/**
* How many frames in last second.
* @type {number}
*/
this.frames = 0;
/**
* Time of last second.
* @type {number}
*/
this._timeLastSecond = 0;
this.game = game;
this._started = 0;
this._timeLastSecond = this._started;
this.time = this._started;
}
Object.defineProperty(TimeManager.prototype, "totalElapsedSeconds", {
get: /**
*
* @method totalElapsedSeconds
* @return {Number}
*/
function () {
return (this.now - this._started) * 0.001;
},
enumerable: true,
configurable: true
});
TimeManager.prototype.update = /**
* Update clock and calculate the fps.
* This is called automatically by Game._raf
* @method update
* @param {number} raf The current timestamp, either performance.now or Date.now
*/
function (raf) {
this.now = raf// mark
;
//this.now = Date.now(); // mark
this.delta = this.now - this.time// elapsedMS
;
this.msMin = Math.min(this.msMin, this.delta);
this.msMax = Math.max(this.msMax, this.delta);
this.frames++;
if(this.now > this._timeLastSecond + 1000) {
this.fps = Math.round((this.frames * 1000) / (this.now - this._timeLastSecond));
this.fpsMin = Math.min(this.fpsMin, this.fps);
this.fpsMax = Math.max(this.fpsMax, this.fps);
this._timeLastSecond = this.now;
this.frames = 0;
}
this.time = this.now// _total
;
};
TimeManager.prototype.elapsedSince = /**
* How long has passed since given time.
* @method elapsedSince
* @param {number} since The time you want to measure.
* @return {number} Duration between given time and now.
*/
function (since) {
return this.now - since;
};
TimeManager.prototype.elapsedSecondsSince = /**
* How long has passed since give time (in seconds).
* @method elapsedSecondsSince
* @param {number} since The time you want to measure (in seconds).
* @return {number} Duration between given time and now (in seconds).
*/
function (since) {
return (this.now - since) * 0.001;
};
TimeManager.prototype.reset = /**
* Set the start time to now.
* @method reset
*/
function () {
this._started = this.now;
};
return TimeManager;
})();
Phaser.TimeManager = TimeManager;
})(Phaser || (Phaser = {}));
/// World
with specific width and height.
*
* @param width {number} Width of the world bound.
* @param height {number} Height of the world bound.
*/
function World(game, width, height) {
/**
* Object container stores every object created with `create*` methods.
* @type {Group}
*/
this._groupCounter = 0;
this._game = game;
this.cameras = new Phaser.CameraManager(this._game, 0, 0, width, height);
this.bounds = new Phaser.Rectangle(0, 0, width, height);
}
World.prototype.getNextGroupID = function () {
return this._groupCounter++;
};
World.prototype.boot = /**
* Called once by Game during the boot process.
*/
function () {
this.group = new Phaser.Group(this._game, 0);
};
World.prototype.update = /**
* This is called automatically every frame, and is where main logic happens.
*/
function () {
this.group.update();
this.cameras.update();
};
World.prototype.postUpdate = /**
* This is called automatically every frame, and is where main logic happens.
*/
function () {
this.group.postUpdate();
this.cameras.postUpdate();
};
World.prototype.destroy = /**
* Clean up memory.
*/
function () {
this.group.destroy();
this.cameras.destroy();
};
World.prototype.setSize = /**
* Updates the size of this world.
*
* @param width {number} New width of the world.
* @param height {number} New height of the world.
* @param [updateCameraBounds] {boolean} Update camera bounds automatically or not. Default to true.
*/
function (width, height, updateCameraBounds) {
if (typeof updateCameraBounds === "undefined") { updateCameraBounds = true; }
this.bounds.width = width;
this.bounds.height = height;
if(updateCameraBounds == true) {
this._game.camera.setBounds(0, 0, width, height);
}
// dispatch world resize event
};
Object.defineProperty(World.prototype, "width", {
get: function () {
return this.bounds.width;
},
set: function (value) {
this.bounds.width = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(World.prototype, "height", {
get: function () {
return this.bounds.height;
},
set: function (value) {
this.bounds.height = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(World.prototype, "centerX", {
get: function () {
return this.bounds.halfWidth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(World.prototype, "centerY", {
get: function () {
return this.bounds.halfHeight;
},
enumerable: true,
configurable: true
});
Object.defineProperty(World.prototype, "randomX", {
get: function () {
return Math.round(Math.random() * this.bounds.width);
},
enumerable: true,
configurable: true
});
Object.defineProperty(World.prototype, "randomY", {
get: function () {
return Math.round(Math.random() * this.bounds.height);
},
enumerable: true,
configurable: true
});
World.prototype.getAllCameras = /**
* Get all the cameras.
*
* @returns {array} An array contains all the cameras.
*/
function () {
return this.cameras.getAll();
};
return World;
})();
Phaser.World = World;
})(Phaser || (Phaser = {}));
/// Phaser.Game
object.
*
* @param callbackContext Which context will the callbacks be called with.
* @param parent {string} ID of its parent DOM element.
* @param width {number} The width of your game in game pixels.
* @param height {number} The height of your game in game pixels.
* @param initCallback {function} Init callback invoked when init default screen.
* @param createCallback {function} Create callback invoked when create default screen.
* @param updateCallback {function} Update callback invoked when update default screen.
* @param renderCallback {function} Render callback invoked when render default screen.
* @param destroyCallback {function} Destroy callback invoked when state is destroyed.
*/
function Game(callbackContext, parent, width, height, initCallback, createCallback, updateCallback, renderCallback, destroyCallback) {
if (typeof parent === "undefined") { parent = ''; }
if (typeof width === "undefined") { width = 800; }
if (typeof height === "undefined") { height = 600; }
if (typeof initCallback === "undefined") { initCallback = null; }
if (typeof createCallback === "undefined") { createCallback = null; }
if (typeof updateCallback === "undefined") { updateCallback = null; }
if (typeof renderCallback === "undefined") { renderCallback = null; }
if (typeof destroyCallback === "undefined") { destroyCallback = null; }
var _this = this;
/**
* Milliseconds of time per step of the game loop.
* @type {number}
*/
this._step = 0;
/**
* Whether load complete loading or not.
* @type {boolean}
*/
this._loadComplete = false;
/**
* Game is paused?
* @type {boolean}
*/
this._paused = false;
/**
* The state to be switched to in the next frame.
* @type {State}
*/
this._pendingState = null;
/**
* The current State object (defaults to null)
* @type {State}
*/
this.state = null;
/**
* This will be called when init states. (loading assets...)
* @type {function}
*/
this.onInitCallback = null;
/**
* This will be called when create states. (setup states...)
* @type {function}
*/
this.onCreateCallback = null;
/**
* This will be called when State is updated, this doesn't happen during load (see onLoadUpdateCallback)
* @type {function}
*/
this.onUpdateCallback = null;
/**
* This will be called when the State is rendered, this doesn't happen during load (see onLoadRenderCallback)
* @type {function}
*/
this.onRenderCallback = null;
/**
* This will be called before the State is rendered and before the stage is cleared
* @type {function}
*/
this.onPreRenderCallback = null;
/**
* This will be called when the State is updated but only during the load process
* @type {function}
*/
this.onLoadUpdateCallback = null;
/**
* This will be called when the State is rendered but only during the load process
* @type {function}
*/
this.onLoadRenderCallback = null;
/**
* This will be called when states paused.
* @type {function}
*/
this.onPausedCallback = null;
/**
* This will be called when the state is destroyed (i.e. swapping to a new state)
* @type {function}
*/
this.onDestroyCallback = null;
/**
* Whether the game engine is booted, aka available.
* @type {boolean}
*/
this.isBooted = false;
/**
* Is game running or paused?
* @type {boolean}
*/
this.isRunning = false;
this.id = Phaser.GAMES.push(this) - 1;
this.callbackContext = callbackContext;
this.onInitCallback = initCallback;
this.onCreateCallback = createCallback;
this.onUpdateCallback = updateCallback;
this.onRenderCallback = renderCallback;
this.onDestroyCallback = destroyCallback;
if(document.readyState === 'complete' || document.readyState === 'interactive') {
setTimeout(function () {
return Phaser.GAMES[_this.id].boot(parent, width, height);
});
} else {
document.addEventListener('DOMContentLoaded', Phaser.GAMES[this.id].boot(parent, width, height), false);
window.addEventListener('load', Phaser.GAMES[this.id].boot(parent, width, height), false);
}
}
Game.prototype.boot = /**
* Initialize engine sub modules and start the game.
* @param parent {string} ID of parent Dom element.
* @param width {number} Width of the game screen.
* @param height {number} Height of the game screen.
*/
function (parent, width, height) {
var _this = this;
if(this.isBooted == true) {
return;
}
if(!document.body) {
setTimeout(function () {
return Phaser.GAMES[_this.id].boot(parent, width, height);
}, 13);
} else {
document.removeEventListener('DOMContentLoaded', Phaser.GAMES[this.id].boot);
window.removeEventListener('load', Phaser.GAMES[this.id].boot);
this.device = new Phaser.Device();
this.net = new Phaser.Net(this);
this.math = new Phaser.GameMath(this);
this.stage = new Phaser.Stage(this, parent, width, height);
this.world = new Phaser.World(this, width, height);
this.add = new Phaser.GameObjectFactory(this);
this.cache = new Phaser.Cache(this);
this.load = new Phaser.Loader(this, this.loadComplete);
this.time = new Phaser.TimeManager(this);
this.tweens = new Phaser.TweenManager(this);
this.input = new Phaser.InputManager(this);
this.sound = new Phaser.SoundManager(this);
this.rnd = new Phaser.RandomDataGenerator([
(Date.now() * Math.random()).toString()
]);
this.physics = new Phaser.Physics.Manager(this);
this.plugins = new Phaser.PluginManager(this, this);
this.setRenderer(Phaser.Types.RENDERER_CANVAS);
this.world.boot();
this.stage.boot();
this.input.boot();
this.isBooted = true;
// Set-up some static helper references
Phaser.DebugUtils.game = this;
Phaser.ColorUtils.game = this;
Phaser.DebugUtils.context = this.stage.context;
// Display the default game screen?
if(this.onInitCallback == null && this.onCreateCallback == null && this.onUpdateCallback == null && this.onRenderCallback == null && this._pendingState == null) {
this._raf = new Phaser.RequestAnimationFrame(this, this.bootLoop);
} else {
this.isRunning = true;
this._loadComplete = false;
this._raf = new Phaser.RequestAnimationFrame(this, this.loop);
if(this._pendingState) {
this.switchState(this._pendingState, false, false);
} else {
this.startState();
}
}
}
};
Game.prototype.setRenderer = function (type) {
switch(type) {
case Phaser.Types.RENDERER_AUTO_DETECT:
this.renderer = new Phaser.HeadlessRenderer(this);
break;
case Phaser.Types.RENDERER_AUTO_DETECT:
case Phaser.Types.RENDERER_CANVAS:
this.renderer = new Phaser.CanvasRenderer(this);
break;
// WebGL coming soon :)
}
};
Game.prototype.loadComplete = /**
* Called when the load has finished after init was run.
*/
function () {
this._loadComplete = true;
};
Game.prototype.bootLoop = /**
* The bootLoop is called while the game is still booting (waiting for the DOM and resources to be available)
*/
function () {
this.tweens.update();
this.input.update();
this.stage.update();
};
Game.prototype.pausedLoop = /**
* The pausedLoop is called when the game is paused.
*/
function () {
this.tweens.update();
this.input.update();
this.stage.update();
this.sound.update();
if(this.onPausedCallback !== null) {
this.onPausedCallback.call(this.callbackContext);
}
};
Game.prototype.emptyCallback = function () {
// Called by onUpdateCallback etc
};
Game.prototype.loop = /**
* Game loop method will be called when it's running.
*/
function () {
this.plugins.preUpdate();
this.tweens.update();
this.input.update();
this.stage.update();
this.sound.update();
//this.physics.update();
this.world.update();
this.plugins.update();
if(this._loadComplete && this.onUpdateCallback) {
this.onUpdateCallback.call(this.callbackContext);
} else if(this._loadComplete == false && this.onLoadUpdateCallback) {
this.onLoadUpdateCallback.call(this.callbackContext);
}
this.world.postUpdate();
this.plugins.postUpdate();
this.plugins.preRender();
if(this._loadComplete && this.onPreRenderCallback) {
this.onPreRenderCallback.call(this.callbackContext);
}
this.renderer.render();
this.plugins.render();
if(this._loadComplete && this.onRenderCallback) {
this.onRenderCallback.call(this.callbackContext);
} else if(this._loadComplete == false && this.onLoadRenderCallback) {
this.onLoadRenderCallback.call(this.callbackContext);
}
this.plugins.postRender();
};
Game.prototype.startState = /**
* Start current state.
*/
function () {
if(this.onInitCallback !== null) {
this.load.reset();
this.onInitCallback.call(this.callbackContext);
// Is the load empty?
if(this.load.queueSize == 0) {
if(this.onCreateCallback !== null) {
this.onCreateCallback.call(this.callbackContext);
}
this._loadComplete = true;
}
} else {
// No init? Then there was nothing to load either
if(this.onCreateCallback !== null) {
this.onCreateCallback.call(this.callbackContext);
}
this._loadComplete = true;
}
};
Game.prototype.setCallbacks = /**
* Set the most common state callbacks (init, create, update, render).
* @param initCallback {function} Init callback invoked when init state.
* @param createCallback {function} Create callback invoked when create state.
* @param updateCallback {function} Update callback invoked when update state.
* @param renderCallback {function} Render callback invoked when render state.
* @param destroyCallback {function} Destroy callback invoked when state is destroyed.
*/
function (initCallback, createCallback, updateCallback, renderCallback, destroyCallback) {
if (typeof initCallback === "undefined") { initCallback = null; }
if (typeof createCallback === "undefined") { createCallback = null; }
if (typeof updateCallback === "undefined") { updateCallback = null; }
if (typeof renderCallback === "undefined") { renderCallback = null; }
if (typeof destroyCallback === "undefined") { destroyCallback = null; }
this.onInitCallback = initCallback;
this.onCreateCallback = createCallback;
this.onUpdateCallback = updateCallback;
this.onRenderCallback = renderCallback;
this.onDestroyCallback = destroyCallback;
};
Game.prototype.switchState = /**
* Switch to a new State.
* @param state {State} The state you want to switch to.
* @param [clearWorld] {boolean} clear everything in the world? (Default to true)
* @param [clearCache] {boolean} clear asset cache? (Default to false and ONLY available when clearWorld=true)
*/
function (state, clearWorld, clearCache) {
if (typeof clearWorld === "undefined") { clearWorld = true; }
if (typeof clearCache === "undefined") { clearCache = false; }
if(this.isBooted == false) {
this._pendingState = state;
return;
}
// Destroy current state?
if(this.onDestroyCallback !== null) {
this.onDestroyCallback.call(this.callbackContext);
}
this.input.reset(true);
// Prototype?
if(typeof state === 'function') {
this.state = new state(this);
}
// Ok, have we got the right functions?
if(this.state['create'] || this.state['update']) {
this.callbackContext = this.state;
this.onInitCallback = null;
this.onLoadRenderCallback = null;
this.onLoadUpdateCallback = null;
this.onCreateCallback = null;
this.onUpdateCallback = null;
this.onRenderCallback = null;
this.onPreRenderCallback = null;
this.onPausedCallback = null;
this.onDestroyCallback = null;
// Bingo, let's set them up
if(this.state['init']) {
this.onInitCallback = this.state['init'];
}
if(this.state['loadRender']) {
this.onLoadRenderCallback = this.state['loadRender'];
}
if(this.state['loadUpdate']) {
this.onLoadUpdateCallback = this.state['loadUpdate'];
}
if(this.state['create']) {
this.onCreateCallback = this.state['create'];
}
if(this.state['update']) {
this.onUpdateCallback = this.state['update'];
}
if(this.state['preRender']) {
this.onPreRenderCallback = this.state['preRender'];
}
if(this.state['render']) {
this.onRenderCallback = this.state['render'];
}
if(this.state['paused']) {
this.onPausedCallback = this.state['paused'];
}
if(this.state['destroy']) {
this.onDestroyCallback = this.state['destroy'];
}
if(clearWorld) {
this.world.destroy();
if(clearCache == true) {
this.cache.destroy();
}
}
this._loadComplete = false;
this.startState();
} else {
throw new Error("Invalid State object given. Must contain at least a create or update function.");
}
};
Game.prototype.destroy = /**
* Nuke the entire game from orbit
*/
function () {
this.callbackContext = null;
this.onInitCallback = null;
this.onLoadRenderCallback = null;
this.onLoadUpdateCallback = null;
this.onCreateCallback = null;
this.onUpdateCallback = null;
this.onRenderCallback = null;
this.onPausedCallback = null;
this.onDestroyCallback = null;
this.cache = null;
this.input = null;
this.load = null;
this.sound = null;
this.stage = null;
this.time = null;
this.world = null;
this.isBooted = false;
};
Object.defineProperty(Game.prototype, "paused", {
get: function () {
return this._paused;
},
set: function (value) {
if(value == true && this._paused == false) {
this._paused = true;
this.sound.pauseAll();
this._raf.callback = this.pausedLoop;
} else if(value == false && this._paused == true) {
this._paused = false;
//this.time.time = window.performance.now ? (performance.now() + performance.timing.navigationStart) : Date.now();
this.input.reset();
this.sound.resumeAll();
if(this.isRunning == false) {
this._raf.callback = this.bootLoop;
} else {
this._raf.callback = this.loop;
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(Game.prototype, "camera", {
get: function () {
return this.world.cameras.current;
},
enumerable: true,
configurable: true
});
return Game;
})();
Phaser.Game = Game;
})(Phaser || (Phaser = {}));
/// Animation
.
*
* @param parent {Sprite} Owner sprite of this animation.
* @param frameData {FrameData} The FrameData object contains animation data.
* @param name {string} Unique name of this animation.
* @param frames {number[]/string[]} An array of numbers or strings indicating what frames to play in what order.
* @param delay {number} Time between frames in ms.
* @param looped {boolean} Whether or not the animation is looped or just plays once.
*/
function Animation(game, parent, frameData, name, frames, delay, looped) {
this._game = game;
this._parent = parent;
this._frames = frames;
this._frameData = frameData;
this.name = name;
this.delay = 1000 / delay;
this.looped = looped;
this.isFinished = false;
this.isPlaying = false;
this._frameIndex = 0;
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
}
Object.defineProperty(Animation.prototype, "frameTotal", {
get: function () {
return this._frames.length;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Animation.prototype, "frame", {
get: function () {
if(this.currentFrame !== null) {
return this.currentFrame.index;
} else {
return this._frameIndex;
}
},
set: function (value) {
this.currentFrame = this._frameData.getFrame(value);
if(this.currentFrame !== null) {
this._parent.texture.width = this.currentFrame.width;
this._parent.texture.height = this.currentFrame.height;
this._frameIndex = value;
}
},
enumerable: true,
configurable: true
});
Animation.prototype.play = /**
* Play this animation.
* @param frameRate {number} FrameRate you want to specify instead of using default.
* @param loop {boolean} Whether or not the animation is looped or just plays once.
*/
function (frameRate, loop) {
if (typeof frameRate === "undefined") { frameRate = null; }
if(frameRate !== null) {
this.delay = 1000 / frameRate;
}
if(loop !== undefined) {
this.looped = loop;
}
this.isPlaying = true;
this.isFinished = false;
this._timeLastFrame = this._game.time.now;
this._timeNextFrame = this._game.time.now + this.delay;
this._frameIndex = 0;
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
this._parent.events.onAnimationStart.dispatch(this._parent, this);
return this;
};
Animation.prototype.restart = /**
* Play this animation from the first frame.
*/
function () {
this.isPlaying = true;
this.isFinished = false;
this._timeLastFrame = this._game.time.now;
this._timeNextFrame = this._game.time.now + this.delay;
this._frameIndex = 0;
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
};
Animation.prototype.stop = /**
* Stop playing animation and set it finished.
*/
function () {
this.isPlaying = false;
this.isFinished = true;
};
Animation.prototype.update = /**
* Update animation frames.
*/
function () {
if(this.isPlaying == true && this._game.time.now >= this._timeNextFrame) {
this._frameIndex++;
if(this._frameIndex == this._frames.length) {
if(this.looped) {
this._frameIndex = 0;
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
this._parent.events.onAnimationLoop.dispatch(this._parent, this);
} else {
this.onComplete();
}
} else {
this.currentFrame = this._frameData.getFrame(this._frames[this._frameIndex]);
}
this._timeLastFrame = this._game.time.now;
this._timeNextFrame = this._game.time.now + this.delay;
return true;
}
return false;
};
Animation.prototype.destroy = /**
* Clean up animation memory.
*/
function () {
this._game = null;
this._parent = null;
this._frames = null;
this._frameData = null;
this.currentFrame = null;
this.isPlaying = false;
};
Animation.prototype.onComplete = /**
* Animation complete callback method.
*/
function () {
this.isPlaying = false;
this.isFinished = true;
this._parent.events.onAnimationComplete.dispatch(this._parent, this);
};
return Animation;
})();
Phaser.Animation = Animation;
})(Phaser || (Phaser = {}));
/// State
.
*/
function State(game) {
this.game = game;
this.add = game.add;
this.camera = game.camera;
this.cache = game.cache;
this.input = game.input;
this.load = game.load;
this.math = game.math;
this.sound = game.sound;
this.stage = game.stage;
this.time = game.time;
this.tweens = game.tweens;
this.world = game.world;
}
State.prototype.init = // Override these in your own States
/**
* Override this method to add some load operations.
* If you need to use the loader, you may need to use them here.
*/
function () {
};
State.prototype.create = /**
* This method is called after the game engine successfully switches states.
* Feel free to add any setup code here.(Do not load anything here, override init() instead)
*/
function () {
};
State.prototype.update = /**
* Put update logic here.
*/
function () {
};
State.prototype.render = /**
* Put render operations here.
*/
function () {
};
State.prototype.paused = /**
* This method will be called when game paused.
*/
function () {
};
State.prototype.destroy = /**
* This method will be called when the state is destroyed
*/
function () {
};
return State;
})();
Phaser.State = State;
/**
* Checks for overlaps between two objects using the world QuadTree. Can be GameObject vs. GameObject, GameObject vs. Group or Group vs. Group.
* Note: Does not take the objects scrollFactor into account. All overlaps are check in world space.
* @param object1 The first GameObject or Group to check. If null the world.group is used.
* @param object2 The second GameObject or Group to check.
* @param notifyCallback A callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you passed them to Collision.overlap.
* @param processCallback A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then notifyCallback will only be called if processCallback returns true.
* @param context The context in which the callbacks will be called
* @returns {boolean} true if the objects overlap, otherwise false.
*/
//public collide(objectOrGroup1 = null, objectOrGroup2 = null, notifyCallback = null, context? = this.game.callbackContext): bool {
// return this.collision.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, Collision.separate, context);
//}
})(Phaser || (Phaser = {}));