diff --git a/Phaser/components/sprite/Input.ts b/Phaser/components/sprite/Input.ts
index 6adac87f..16d87575 100644
--- a/Phaser/components/sprite/Input.ts
+++ b/Phaser/components/sprite/Input.ts
@@ -48,6 +48,11 @@ module Phaser.Components.Sprite {
*/
public priorityID:number = 0;
+ /**
+ * The index of this Input component entry in the Game.Input manager.
+ */
+ public indexID:number = 0;
+
private _dragPoint: Point;
private _draggedPointerID: number;
public dragOffset: Point;
@@ -58,6 +63,7 @@ module Phaser.Components.Sprite {
public allowHorizontalDrag: bool = true;
public allowVerticalDrag: bool = true;
+ public bringToTop: bool = false;
public snapOnDrag: bool = false;
public snapOnRelease: bool = false;
@@ -245,11 +251,26 @@ module Phaser.Components.Sprite {
{
// De-register, etc
this.enabled = false;
- this.game.input.removeGameObject(this.sprite);
+ this.game.input.removeGameObject(this.indexID);
}
}
+ /**
+ * Clean up memory.
+ */
+ public destroy() {
+
+ if (this.enabled)
+ {
+ this.game.input.removeGameObject(this.indexID);
+ }
+
+ }
+
+ /**
+ * Checks if the given pointer is over this Sprite. All checks are done in world coordinates.
+ */
public checkPointerOver(pointer: Phaser.Pointer): bool {
if (this.enabled == false || this.sprite.visible == false)
@@ -258,7 +279,7 @@ module Phaser.Components.Sprite {
}
else
{
- return RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY());
+ return SpriteUtils.overlapsXY(this.sprite, pointer.worldX(), pointer.worldY());
}
}
@@ -279,7 +300,7 @@ module Phaser.Components.Sprite {
}
else if (this._pointerData[pointer.id].isOver == true)
{
- if (RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY()))
+ if (SpriteUtils.overlapsXY(this.sprite, pointer.worldX(), pointer.worldY()))
{
this._pointerData[pointer.id].x = pointer.x - this.sprite.x;
this._pointerData[pointer.id].y = pointer.y - this.sprite.y;
@@ -350,6 +371,11 @@ module Phaser.Components.Sprite {
this.startDrag(pointer);
}
+ if (this.bringToTop)
+ {
+ this.sprite.group.bringToTop(this.sprite);
+ }
+
}
// Consume the event?
@@ -493,16 +519,18 @@ module Phaser.Components.Sprite {
* Make this Sprite draggable by the mouse. You can also optionally set mouseStartDragCallback and mouseStopDragCallback
*
* @param lockCenter If false the Sprite will drag from where you click it minus the dragOffset. If true it will center itself to the tip of the mouse pointer.
+ * @param bringToTop If true the Sprite will be bought to the top of the rendering list in its current Group.
* @param pixelPerfect If true it will use a pixel perfect test to see if you clicked the Sprite. False uses the bounding box.
* @param alphaThreshold If using pixel perfect collision this specifies the alpha level from 0 to 255 above which a collision is processed (default 255)
* @param boundsRect If you want to restrict the drag of this sprite to a specific FlxRect, pass the FlxRect here, otherwise it's free to drag anywhere
* @param boundsSprite If you want to restrict the drag of this sprite to within the bounding box of another sprite, pass it here
*/
- public enableDrag(lockCenter:bool = false, pixelPerfect:bool = false, alphaThreshold:number = 255, boundsRect:Rectangle = null, boundsSprite:Phaser.Sprite = null):void
+ public enableDrag(lockCenter:bool = false, bringToTop:bool = false, pixelPerfect:bool = false, alphaThreshold:number = 255, boundsRect:Rectangle = null, boundsSprite:Phaser.Sprite = null):void
{
this._dragPoint = new Point;
this.draggable = true;
+ this.bringToTop = bringToTop;
this.dragOffset = new Point;
this.dragFromCenter = lockCenter;
@@ -559,6 +587,11 @@ module Phaser.Components.Sprite {
this.updateDrag(pointer);
+ if (this.bringToTop)
+ {
+ this.sprite.group.bringToTop(this.sprite);
+ }
+
}
/**
diff --git a/Phaser/core/Group.ts b/Phaser/core/Group.ts
index ad9397d7..812b0791 100644
--- a/Phaser/core/Group.ts
+++ b/Phaser/core/Group.ts
@@ -583,6 +583,14 @@ module Phaser {
}
+ /**
+ * 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.
+ */
public swap(child1, child2, sort?: bool = true): bool {
if (child1.group.ID != this.ID || child2.group.ID != this.ID || child1 === child2)
@@ -604,6 +612,43 @@ module Phaser {
}
+ public bringToTop(child): bool {
+
+ // If child not in this group, or is already at the top of the group, return false
+ if (child.group.ID != this.ID || child.z == this._zCounter)
+ {
+ return false;
+ }
+
+ this.sort();
+
+ // What's the z index of the top most child?
+ var tempZ: number = child.z;
+ var childIndex: number = this._zCounter;
+
+ this._i = 0;
+
+ while (this._i < this.length)
+ {
+ this._member = this.members[this._i++];
+
+ if (this._i > childIndex)
+ {
+ this._member.z--;
+ }
+ else if (this._member.z == child.z)
+ {
+ childIndex = this._i;
+ this._member.z = this._zCounter;
+ }
+ }
+
+ this.sort();
+
+ return true;
+
+ }
+
/**
* 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
diff --git a/Phaser/gameobjects/Sprite.ts b/Phaser/gameobjects/Sprite.ts
index 74d2176d..488bf62f 100644
--- a/Phaser/gameobjects/Sprite.ts
+++ b/Phaser/gameobjects/Sprite.ts
@@ -40,7 +40,6 @@ module Phaser {
this.z = -1;
this.group = null;
- // No dependencies
this.animations = new Phaser.Components.AnimationManager(this);
this.input = new Phaser.Components.Sprite.Input(this);
this.events = new Phaser.Components.Sprite.Events(this);
@@ -74,6 +73,11 @@ module Phaser {
this.transform.setCache();
+ // Handy proxies
+ this.scale = this.transform.scale;
+ this.alpha = this.texture.alpha;
+ this.origin = this.transform.origin;
+
}
/**
@@ -194,6 +198,23 @@ module Phaser {
this.transform.rotation = this.game.math.wrap(value, 360, 0);
}
+ /**
+ * The scale of the Sprite. A value of 1 is original scale. 0.5 is half size. 2 is double the size.
+ * This is a reference to Sprite.transform.scale
+ */
+ public scale: Phaser.Vec2;
+
+ /**
+ * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque.
+ */
+ public alpha: number;
+
+ /**
+ * The origin of the Sprite around which rotation and positioning takes place.
+ * This is a reference to Sprite.transform.origin
+ */
+ public origin: Phaser.Vec2;
+
/**
* Set the animation frame by frame number.
*/
@@ -318,8 +339,7 @@ module Phaser {
*/
public destroy() {
- //this.input.destroy();
-
+ this.input.destroy();
}
diff --git a/Phaser/input/Input.ts b/Phaser/input/Input.ts
index 6c76469d..32ed80cd 100644
--- a/Phaser/input/Input.ts
+++ b/Phaser/input/Input.ts
@@ -455,22 +455,46 @@ module Phaser {
public inputObjects = [];
public totalTrackedObjects: number = 0;
- // Add Input Enabled array + add/remove methods and then iterate and update them during the main update
- // Clear down this array on State swap??? Maybe removed from it when Sprite is destroyed
-
+ /**
+ * Adds a new game object to be tracked by the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method addGameObject
+ **/
public addGameObject(object) {
- // Lots more checks here
+ // Find a spare slot
+ for (var i = 0; i < this.inputObjects.length; i++)
+ {
+ if (this.inputObjects[i] == null)
+ {
+ this.inputObjects[i] = object;
+ object.input.indexID = i;
+ this.totalTrackedObjects++;
+ return;
+ }
+ }
+
+ // If we got this far we need to push a new entry into the array
+ object.input.indexID = this.inputObjects.length;
+
this.inputObjects.push(object);
+
this.totalTrackedObjects++;
+
}
- public removeGameObject(object) {
- // TODO
+ /**
+ * Removes a game object from the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method removeGameObject
+ **/
+ public removeGameObject(index: number) {
+
+ if (this.inputObjects[index])
+ {
+ this.inputObjects[index] = null;
+ }
+
}
-
-
/**
* Updates the Input Manager. Called by the core Game loop.
* @method update
@@ -521,7 +545,7 @@ module Phaser {
if (this.pointer10) { this.pointer10.reset(); }
this.currentPointers = 0;
-
+
this._game.stage.canvas.style.cursor = "default";
if (hard == true)
@@ -618,7 +642,7 @@ module Phaser {
* @param {Any} event The event data from the Touch event
* @return {Pointer} The Pointer object that was started or null if no Pointer object is available
**/
- public startPointer(event):Pointer {
+ public startPointer(event): Pointer {
if (this.maxPointers < 10 && this.totalActivePointers == this.maxPointers)
{
@@ -677,7 +701,7 @@ module Phaser {
* @param {Any} event The event data from the Touch event
* @return {Pointer} The Pointer object that was updated or null if no Pointer object is available
**/
- public updatePointer(event):Pointer {
+ public updatePointer(event): Pointer {
// Unrolled for speed
if (this.pointer1.active == true && this.pointer1.identifier == event.identifier)
@@ -731,7 +755,7 @@ module Phaser {
* @param {Any} event The event data from the Touch event
* @return {Pointer} The Pointer object that was stopped or null if no Pointer object is available
**/
- public stopPointer(event):Pointer {
+ public stopPointer(event): Pointer {
// Unrolled for speed
if (this.pointer1.active == true && this.pointer1.identifier == event.identifier)
diff --git a/Phaser/input/Pointer.ts b/Phaser/input/Pointer.ts
index 7b89d213..b854a1ce 100644
--- a/Phaser/input/Pointer.ts
+++ b/Phaser/input/Pointer.ts
@@ -422,7 +422,7 @@ module Phaser {
for (var i = 0; i < this.game.input.totalTrackedObjects; i++)
{
- if (this.game.input.inputObjects[i].input.checkPointerOver(this) && this.game.input.inputObjects[i].renderOrderID > _highestRenderID)
+ if (this.game.input.inputObjects[i] !== null && this.game.input.inputObjects[i].input.checkPointerOver(this) && this.game.input.inputObjects[i].renderOrderID > _highestRenderID)
{
_highestRenderID = this.game.input.inputObjects[i].renderOrderID;
_highestRenderObject = i;
@@ -510,7 +510,7 @@ module Phaser {
for (var i = 0; i < this.game.input.totalTrackedObjects; i++)
{
- if (this.game.input.inputObjects[i].input.enabled)
+ if (this.game.input.inputObjects[i] !== null && this.game.input.inputObjects[i].input.enabled)
{
this.game.input.inputObjects[i].input._releasedHandler(this);
}
diff --git a/Phaser/loader/Cache.ts b/Phaser/loader/Cache.ts
index 4cd8a1dc..94ef30b8 100644
--- a/Phaser/loader/Cache.ts
+++ b/Phaser/loader/Cache.ts
@@ -261,6 +261,57 @@ module Phaser {
}
+ /**
+ * Returns an array containing all of the keys of Images in the Cache.
+ * @return {Array} The string based keys in the Cache.
+ */
+ public getImageKeys() {
+
+ var output = [];
+
+ for (var item in this._images)
+ {
+ output.push(item);
+ }
+
+ return output;
+
+ }
+
+ /**
+ * Returns an array containing all of the keys of Sounds in the Cache.
+ * @return {Array} The string based keys in the Cache.
+ */
+ public getSoundKeys() {
+
+ var output = [];
+
+ for (var item in this._sounds)
+ {
+ output.push(item);
+ }
+
+ return output;
+
+ }
+
+ /**
+ * Returns an array containing all of the keys of Text Files in the Cache.
+ * @return {Array} The string based keys in the Cache.
+ */
+ public getTextKeys() {
+
+ var output = [];
+
+ for (var item in this._text)
+ {
+ output.push(item);
+ }
+
+ return output;
+
+ }
+
/**
* Clean up cache memory.
*/
diff --git a/README.md b/README.md
index bdc6655a..eefeff1e 100644
--- a/README.md
+++ b/README.md
@@ -33,18 +33,15 @@ TODO:
* If the Camera is larger than the Stage size then the rotation offset isn't correct
* Texture Repeat doesn't scroll, because it's part of the camera not the world, need to think about this more
* Bug: Sprite x/y gets shifted if dynamic from the original value
-* Input CSS cursor those little 4-way arrows on drag?
* Stage CSS3 transforms!!! Color tints, sepia, greyscale, all of those cool things :)
* Add JSON Texture Atlas object support.
* Swap to using time based motion (like the tweens) rather than delta timer - it just doesn't work well on slow phones
* Pointer.getWorldX(camera) needs to take camera scale into consideration
-* Add a 'click to bring to top' demo (+ Group feature?)
* If stage.clear set to false and game pauses, when it unpauses you still see the pause arrow - resolve this
* Add clip support + shape options to Texture Component.
* Make sure I'm using Point and not Vec2 when it's not a directional vector I need
* Bug with setting scale or anything on a Sprite inside a Group, or maybe group.addNewSprite issue
-* Make input check use the rotated sprite check
* Sprite collision events
* See which functions in the input component can move elsewhere (utils)
* Move all of the renderDebugInfo methods to the DebugUtils class
@@ -113,6 +110,8 @@ V1.0.0
* Camera.inCamera check now uses the Sprite.worldView which finally accurately updates regardless of scale, rotation or rotation origin.
* Added Math.Mat3 for Matrix3 operations (which Sprite.Transform uses) and Math.Mat3Utils for lots of use Mat3 related methods.
* Added SpriteUtils.overlapsXY and overlapsPoint to check if a point is within a sprite, taking scale and rotation into account.
+* Added Cache.getImageKeys (and similar) to return an array of all the keys for all currently cached objects.
+* Added Group.bringToTop feature. Will sort the Group, move the given sprites z-index to the top and shift the rest down by one.
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 7d503fff..a4bdc215 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -85,6 +85,10 @@
GameObject were located at the given position, would it overlap the GameObject or Group?
- * This is distinct from overlapsPoint(), which just checks that point, rather than taking the object's size into account.
- * WARNING: Currently tilemaps do NOT support screen space overlap checks!
- *
- * @param X {number} The X position you want to check. Pretends this object (the caller, not the parameter) is located here.
- * @param Y {number} The Y position you want to check. Pretends this object (the caller, not the parameter) is located here.
- * @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 two objects overlap.
- */
- /*
- static overlapsAt(X: number, Y: number, objectOrGroup, inScreenSpace: bool = false, camera: Camera = null): bool {
-
- if (objectOrGroup.isGroup)
- {
- var results: bool = false;
- var basic;
- var i: number = 0;
- var members = objectOrGroup.members;
-
- while (i < length)
- {
- if (this.overlapsAt(X, Y, members[i++], inScreenSpace, camera))
- {
- results = true;
- }
- }
-
- return results;
- }
-
- if (!inScreenSpace)
- {
- return (objectOrGroup.x + objectOrGroup.width > X) && (objectOrGroup.x < X + this.width) &&
- (objectOrGroup.y + objectOrGroup.height > Y) && (objectOrGroup.y < Y + this.height);
- }
-
- if (camera == null)
- {
- camera = this._game.camera;
- }
-
- var objectScreenPos: Point = objectOrGroup.getScreenXY(null, Camera);
-
- this._point.x = X - camera.scroll.x * this.transform.scrollFactor.x; //copied from getScreenXY()
- this._point.y = Y - camera.scroll.y * this.transform.scrollFactor.y;
- this._point.x += (this._point.x > 0) ? 0.0000001 : -0.0000001;
- this._point.y += (this._point.y > 0) ? 0.0000001 : -0.0000001;
-
return (objectScreenPos.x + objectOrGroup.width > this._point.x) && (objectScreenPos.x < this._point.x + this.width) &&
(objectScreenPos.y + objectOrGroup.height > this._point.y) && (objectScreenPos.y < this._point.y + this.height);
}
@@ -4825,52 +4797,32 @@ var Phaser;
if(sprite.transform.rotation == 0) {
return Phaser.RectangleUtils.contains(sprite.cameraView, x, y);
}
- //var ex: number = sprite.transform.upperRight.x - sprite.transform.upperLeft.x;
- //var ey: number = sprite.transform.upperRight.y - sprite.transform.upperLeft.y;
- //var fx: number = sprite.transform.bottomLeft.x - sprite.transform.upperLeft.x;
- //var fy: number = sprite.transform.bottomLeft.y - sprite.transform.upperLeft.y;
- //if ((x-ax)*ex+(y-ay)*ey<0.0) return false;
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-bx)*ex+(y-by)*ey>0.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-ax)*fx+(y-ay)*fy<0.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-dx)*fx+(y-dy)*fy>0.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 a point in 2D world space overlaps this GameObject.
+ * 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.
- * @param inScreenSpace {boolean} Whether to take scroll factors into account when checking for overlap.
- * @param camera {Camera} Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return Whether or not the point overlaps this object.
*/
- function overlapsPoint(sprite, point, inScreenSpace, camera) {
- if (typeof inScreenSpace === "undefined") { inScreenSpace = false; }
- if (typeof camera === "undefined") { camera = null; }
- if(!inScreenSpace) {
- return Phaser.RectangleUtils.containsPoint(sprite.body.bounds, point);
- //return (point.x > sprite.x) && (point.x < sprite.x + sprite.width) && (point.y > sprite.y) && (point.y < sprite.y + sprite.height);
- }
- if(camera == null) {
- camera = sprite.game.camera;
- }
- //var x: number = point.x - camera.scroll.x;
- //var y: number = point.y - camera.scroll.y;
- //this.getScreenXY(this._point, camera);
- //return (x > this._point.x) && (X < this._point.x + this.width) && (Y > this._point.y) && (Y < this._point.y + this.height);
- };
+ function overlapsPoint(sprite, point) {
+ return SpriteUtils.overlapsXY(sprite, point.x, point.y);
+ };
SpriteUtils.onScreen = /**
* Check and see if this object is currently on screen.
*
@@ -4940,15 +4892,6 @@ var Phaser;
sprite.body.position.x = x;
sprite.body.position.y = y;
};
- SpriteUtils.setOriginToCenter = function setOriginToCenter(sprite, fromFrameBounds, fromBody) {
- if (typeof fromFrameBounds === "undefined") { fromFrameBounds = true; }
- if (typeof fromBody === "undefined") { fromBody = false; }
- if(fromFrameBounds) {
- sprite.transform.origin.setTo(sprite.width / 2, sprite.height / 2);
- } else if(fromBody) {
- sprite.transform.origin.setTo(sprite.body.bounds.halfWidth, sprite.body.bounds.halfHeight);
- }
- };
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)
@@ -5535,7 +5478,15 @@ var Phaser;
this.members[this._i] = newObject;
return newObject;
};
- Group.prototype.swap = function (child1, child2, sort) {
+ 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;
@@ -5548,6 +5499,28 @@ var Phaser;
}
return true;
};
+ Group.prototype.bringToTop = function (child) {
+ // If child not in this group, or is already at the top of the group, return false
+ if(child.group.ID != this.ID || child.z == this._zCounter) {
+ return false;
+ }
+ this.sort();
+ // What's the z index of the top most child?
+ var tempZ = child.z;
+ var childIndex = this._zCounter;
+ this._i = 0;
+ while(this._i < this.length) {
+ this._member = this.members[this._i++];
+ if(this._i > childIndex) {
+ this._member.z--;
+ } else if(this._member.z == child.z) {
+ childIndex = this._i;
+ this._member.z = this._zCounter;
+ }
+ }
+ 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
@@ -6832,6 +6805,13 @@ var Phaser;
}
return null;
};
+ Cache.prototype.getImageKeys = function () {
+ var output = [];
+ for(var item in this._images) {
+ output.push(item);
+ }
+ return output;
+ };
Cache.prototype.destroy = /**
* Clean up cache memory.
*/
@@ -14951,7 +14931,7 @@ var Phaser;
var _highestRenderID = -1;
var _highestRenderObject = -1;
for(var i = 0; i < this.game.input.totalTrackedObjects; i++) {
- if(this.game.input.inputObjects[i].input.checkPointerOver(this) && this.game.input.inputObjects[i].renderOrderID > _highestRenderID) {
+ if(this.game.input.inputObjects[i] !== null && this.game.input.inputObjects[i].input.checkPointerOver(this) && this.game.input.inputObjects[i].renderOrderID > _highestRenderID) {
_highestRenderID = this.game.input.inputObjects[i].renderOrderID;
_highestRenderObject = i;
}
@@ -15010,7 +14990,7 @@ var Phaser;
this.game.input.currentPointers--;
}
for(var i = 0; i < this.game.input.totalTrackedObjects; i++) {
- if(this.game.input.inputObjects[i].input.enabled) {
+ if(this.game.input.inputObjects[i] !== null && this.game.input.inputObjects[i].input.enabled) {
this.game.input.inputObjects[i].input._releasedHandler(this);
}
}
@@ -16055,16 +16035,34 @@ var Phaser;
this.gestures.start();
this.mousePointer.active = true;
};
- Input.prototype.addGameObject = // Add Input Enabled array + add/remove methods and then iterate and update them during the main update
- // Clear down this array on State swap??? Maybe removed from it when Sprite is destroyed
+ Input.prototype.addGameObject = /**
+ * Adds a new game object to be tracked by the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method addGameObject
+ **/
function (object) {
- // Lots more checks here
+ // Find a spare slot
+ for(var i = 0; i < this.inputObjects.length; i++) {
+ if(this.inputObjects[i] == null) {
+ this.inputObjects[i] = object;
+ object.input.indexID = i;
+ this.totalTrackedObjects++;
+ return;
+ }
+ }
+ // If we got this far we need to push a new entry into the array
+ object.input.indexID = this.inputObjects.length;
this.inputObjects.push(object);
this.totalTrackedObjects++;
};
- Input.prototype.removeGameObject = function (object) {
- // TODO
- };
+ Input.prototype.removeGameObject = /**
+ * Removes a game object from the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method removeGameObject
+ **/
+ function (index) {
+ if(this.inputObjects[index]) {
+ this.inputObjects[index] = null;
+ }
+ };
Input.prototype.update = /**
* Updates the Input Manager. Called by the core Game loop.
* @method update
diff --git a/Tests/scrollzones/blasteroids.js b/Tests/scrollzones/blasteroids.js
index 474a7023..580e2761 100644
--- a/Tests/scrollzones/blasteroids.js
+++ b/Tests/scrollzones/blasteroids.js
@@ -36,7 +36,7 @@
bullets.add(tempBullet);
}
ship = game.add.sprite(game.stage.centerX, game.stage.centerY, 'nashwan', Phaser.Types.BODY_DYNAMIC);
- Phaser.SpriteUtils.setOriginToCenter(ship);
+ ship.transform.origin.setTo(0.5, 0.5);
// We do this because the ship was drawn facing up, but 0 degrees is pointing to the right
ship.transform.rotationOffset = 90;
game.input.onDown.add(test, this);
diff --git a/Tests/scrollzones/blasteroids.ts b/Tests/scrollzones/blasteroids.ts
index 2877fed1..84bad9e4 100644
--- a/Tests/scrollzones/blasteroids.ts
+++ b/Tests/scrollzones/blasteroids.ts
@@ -53,7 +53,7 @@
}
ship = game.add.sprite(game.stage.centerX, game.stage.centerY, 'nashwan', Phaser.Types.BODY_DYNAMIC);
- Phaser.SpriteUtils.setOriginToCenter(ship);
+ ship.transform.origin.setTo(0.5, 0.5);
// We do this because the ship was drawn facing up, but 0 degrees is pointing to the right
ship.transform.rotationOffset = 90;
diff --git a/Tests/sprites/scale sprite 1.js b/Tests/sprites/scale sprite 1.js
index 33b0e381..5cec160e 100644
--- a/Tests/sprites/scale sprite 1.js
+++ b/Tests/sprites/scale sprite 1.js
@@ -12,9 +12,9 @@
smallBunny = game.add.sprite(0, 0, 'bunny');
// And now let's scale the sprite by half
// You can do either:
- // smallBunny.transform.scale.x = 0.5;
- // smallBunny.transform.scale.y = 0.5;
+ //smallBunny.scale.x = 0.5;
+ //smallBunny.scale.y = 0.5;
// Or you can set them both at the same time using setTo:
- smallBunny.transform.scale.setTo(0.5, 0.5);
+ smallBunny.scale.setTo(0.5, 0.5);
}
})();
diff --git a/Tests/sprites/scale sprite 1.ts b/Tests/sprites/scale sprite 1.ts
index bc04c51e..3c182607 100644
--- a/Tests/sprites/scale sprite 1.ts
+++ b/Tests/sprites/scale sprite 1.ts
@@ -22,11 +22,11 @@
// And now let's scale the sprite by half
// You can do either:
- // smallBunny.transform.scale.x = 0.5;
- // smallBunny.transform.scale.y = 0.5;
+ //smallBunny.scale.x = 0.5;
+ //smallBunny.scale.y = 0.5;
// Or you can set them both at the same time using setTo:
- smallBunny.transform.scale.setTo(0.5, 0.5);
+ smallBunny.scale.setTo(0.5, 0.5);
}
diff --git a/Tests/sprites/sprite origin 3.js b/Tests/sprites/sprite origin 3.js
index 907f6a1b..20ea3979 100644
--- a/Tests/sprites/sprite origin 3.js
+++ b/Tests/sprites/sprite origin 3.js
@@ -14,7 +14,7 @@
fuji = game.add.sprite(game.stage.centerX, game.stage.centerY, 'fuji');
// The sprite is 320 x 200 pixels in size
// Here we set the origin to be the bottom-right of the sprite
- fuji.transform.origin.setTo(320, 200);
+ fuji.origin.setTo(320, 200);
game.add.tween(fuji).to({
rotation: 360
}, 2000, Phaser.Easing.Linear.None, true, 0, true);
diff --git a/Tests/sprites/sprite origin 3.ts b/Tests/sprites/sprite origin 3.ts
index ba966bff..c61f1a3a 100644
--- a/Tests/sprites/sprite origin 3.ts
+++ b/Tests/sprites/sprite origin 3.ts
@@ -24,7 +24,7 @@
// The sprite is 320 x 200 pixels in size
// Here we set the origin to be the bottom-right of the sprite
- fuji.transform.origin.setTo(320, 200);
+ fuji.origin.setTo(320, 200);
game.add.tween(fuji).to({ rotation: 360 }, 2000, Phaser.Easing.Linear.None, true, 0, true);
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index 768901fe..8584ca5c 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -2039,6 +2039,10 @@ module Phaser.Components.Sprite {
* The PriorityID controls which Sprite receives an Input event first if they should overlap.
*/
public priorityID: number;
+ /**
+ * The index of this Input component entry in the Game.Input manager.
+ */
+ public indexID: number;
private _dragPoint;
private _draggedPointerID;
public dragOffset: Point;
@@ -2048,6 +2052,7 @@ module Phaser.Components.Sprite {
public dragPixelPerfectAlpha: number;
public allowHorizontalDrag: bool;
public allowVerticalDrag: bool;
+ public bringToTop: bool;
public snapOnDrag: bool;
public snapOnRelease: bool;
public snapOffset: Point;
@@ -2148,6 +2153,13 @@ module Phaser.Components.Sprite {
public start(priority?: number, checkBody?: bool, useHandCursor?: bool): Sprite;
public reset(): void;
public stop(): void;
+ /**
+ * Clean up memory.
+ */
+ public destroy(): void;
+ /**
+ * Checks if the given pointer is over this Sprite. All checks are done in world coordinates.
+ */
public checkPointerOver(pointer: Pointer): bool;
/**
* Update
@@ -2200,12 +2212,13 @@ module Phaser.Components.Sprite {
* Make this Sprite draggable by the mouse. You can also optionally set mouseStartDragCallback and mouseStopDragCallback
*
* @param lockCenter If false the Sprite will drag from where you click it minus the dragOffset. If true it will center itself to the tip of the mouse pointer.
+ * @param bringToTop If true the Sprite will be bought to the top of the rendering list in its current Group.
* @param pixelPerfect If true it will use a pixel perfect test to see if you clicked the Sprite. False uses the bounding box.
* @param alphaThreshold If using pixel perfect collision this specifies the alpha level from 0 to 255 above which a collision is processed (default 255)
* @param boundsRect If you want to restrict the drag of this sprite to a specific FlxRect, pass the FlxRect here, otherwise it's free to drag anywhere
* @param boundsSprite If you want to restrict the drag of this sprite to within the bounding box of another sprite, pass it here
*/
- public enableDrag(lockCenter?: bool, pixelPerfect?: bool, alphaThreshold?: number, boundsRect?: Rectangle, boundsSprite?: Sprite): void;
+ public enableDrag(lockCenter?: bool, bringToTop?: bool, pixelPerfect?: bool, alphaThreshold?: number, boundsRect?: Rectangle, boundsSprite?: Sprite): void;
/**
* Stops this sprite from being able to be dragged. If it is currently the target of an active drag it will be stopped immediately. Also disables any set callbacks.
*/
@@ -2670,6 +2683,20 @@ module Phaser {
*/
public rotation : number;
/**
+ * The scale of the Sprite. A value of 1 is original scale. 0.5 is half size. 2 is double the size.
+ * This is a reference to Sprite.transform.scale
+ */
+ public scale: Vec2;
+ /**
+ * The alpha of the Sprite between 0 and 1, a value of 1 being fully opaque.
+ */
+ public alpha: number;
+ /**
+ * The origin of the Sprite around which rotation and positioning takes place.
+ * This is a reference to Sprite.transform.origin
+ */
+ public origin: Vec2;
+ /**
* Get the animation frame number.
*/
/**
@@ -2746,15 +2773,15 @@ module Phaser {
*/
static overlapsXY(sprite: Sprite, x: number, y: number): bool;
/**
- * Checks to see if a point in 2D world space overlaps this GameObject.
+ * 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.
- * @param inScreenSpace {boolean} Whether to take scroll factors into account when checking for overlap.
- * @param camera {Camera} Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return Whether or not the point overlaps this object.
*/
- static overlapsPoint(sprite: Sprite, point: Point, inScreenSpace?: bool, camera?: Camera): bool;
+ static overlapsPoint(sprite: Sprite, point: Point): bool;
/**
* Check and see if this object is currently on screen.
*
@@ -2780,7 +2807,6 @@ module Phaser {
* @param y {number} The new Y position of this object.
*/
static reset(sprite: Sprite, x: number, y: number): void;
- static setOriginToCenter(sprite: Sprite, fromFrameBounds?: bool, fromBody?: bool): void;
/**
* 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)
@@ -3139,7 +3165,16 @@ module Phaser {
* @return {Basic} The new object.
*/
public replace(oldObject, newObject);
+ /**
+ * 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.
+ */
public swap(child1, child2, sort?: bool): bool;
+ public bringToTop(child): bool;
/**
* 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
@@ -3797,6 +3832,7 @@ module Phaser {
* @return {object} The text data you want.
*/
public getText(key: string);
+ public getImageKeys(): any[];
/**
* Clean up cache memory.
*/
@@ -8656,8 +8692,16 @@ module Phaser {
public boot(): void;
public inputObjects: any[];
public totalTrackedObjects: number;
+ /**
+ * Adds a new game object to be tracked by the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method addGameObject
+ **/
public addGameObject(object): void;
- public removeGameObject(object): void;
+ /**
+ * Removes a game object from the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method removeGameObject
+ **/
+ public removeGameObject(index: number): void;
/**
* Updates the Input Manager. Called by the core Game loop.
* @method update
diff --git a/build/phaser.js b/build/phaser.js
index 5895e09e..6826f466 100644
--- a/build/phaser.js
+++ b/build/phaser.js
@@ -3310,10 +3310,15 @@ var Phaser;
* The PriorityID controls which Sprite receives an Input event first if they should overlap.
*/
this.priorityID = 0;
+ /**
+ * The index of this Input component entry in the Game.Input manager.
+ */
+ this.indexID = 0;
this.isDragged = false;
this.dragPixelPerfect = false;
this.allowHorizontalDrag = true;
this.allowVerticalDrag = true;
+ this.bringToTop = false;
this.snapOnDrag = false;
this.snapOnRelease = false;
this.snapX = 0;
@@ -3497,14 +3502,25 @@ var Phaser;
} else {
// De-register, etc
this.enabled = false;
- this.game.input.removeGameObject(this.sprite);
+ this.game.input.removeGameObject(this.indexID);
}
};
- Input.prototype.checkPointerOver = function (pointer) {
+ Input.prototype.destroy = /**
+ * Clean up memory.
+ */
+ function () {
+ if(this.enabled) {
+ this.game.input.removeGameObject(this.indexID);
+ }
+ };
+ Input.prototype.checkPointerOver = /**
+ * Checks if the given pointer is over this Sprite. All checks are done in world coordinates.
+ */
+ function (pointer) {
if(this.enabled == false || this.sprite.visible == false) {
return false;
} else {
- return Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY());
+ return Phaser.SpriteUtils.overlapsXY(this.sprite, pointer.worldX(), pointer.worldY());
}
};
Input.prototype.update = /**
@@ -3517,7 +3533,7 @@ var Phaser;
if(this.draggable && this._draggedPointerID == pointer.id) {
return this.updateDrag(pointer);
} else if(this._pointerData[pointer.id].isOver == true) {
- if(Phaser.RectangleUtils.contains(this.sprite.worldView, pointer.worldX(), pointer.worldY())) {
+ if(Phaser.SpriteUtils.overlapsXY(this.sprite, pointer.worldX(), pointer.worldY())) {
this._pointerData[pointer.id].x = pointer.x - this.sprite.x;
this._pointerData[pointer.id].y = pointer.y - this.sprite.y;
return true;
@@ -3561,6 +3577,9 @@ var Phaser;
if(this.draggable && this.isDragged == false) {
this.startDrag(pointer);
}
+ if(this.bringToTop) {
+ this.sprite.group.bringToTop(this.sprite);
+ }
}
// Consume the event?
return this.consumePointerEvent;
@@ -3674,19 +3693,22 @@ var Phaser;
* Make this Sprite draggable by the mouse. You can also optionally set mouseStartDragCallback and mouseStopDragCallback
*
* @param lockCenter If false the Sprite will drag from where you click it minus the dragOffset. If true it will center itself to the tip of the mouse pointer.
+ * @param bringToTop If true the Sprite will be bought to the top of the rendering list in its current Group.
* @param pixelPerfect If true it will use a pixel perfect test to see if you clicked the Sprite. False uses the bounding box.
* @param alphaThreshold If using pixel perfect collision this specifies the alpha level from 0 to 255 above which a collision is processed (default 255)
* @param boundsRect If you want to restrict the drag of this sprite to a specific FlxRect, pass the FlxRect here, otherwise it's free to drag anywhere
* @param boundsSprite If you want to restrict the drag of this sprite to within the bounding box of another sprite, pass it here
*/
- function (lockCenter, pixelPerfect, alphaThreshold, boundsRect, boundsSprite) {
+ function (lockCenter, bringToTop, pixelPerfect, alphaThreshold, boundsRect, boundsSprite) {
if (typeof lockCenter === "undefined") { lockCenter = false; }
+ if (typeof bringToTop === "undefined") { bringToTop = false; }
if (typeof pixelPerfect === "undefined") { pixelPerfect = false; }
if (typeof alphaThreshold === "undefined") { alphaThreshold = 255; }
if (typeof boundsRect === "undefined") { boundsRect = null; }
if (typeof boundsSprite === "undefined") { boundsSprite = null; }
this._dragPoint = new Phaser.Point();
this.draggable = true;
+ this.bringToTop = bringToTop;
this.dragOffset = new Phaser.Point();
this.dragFromCenter = lockCenter;
this.dragPixelPerfect = pixelPerfect;
@@ -3725,6 +3747,9 @@ var Phaser;
this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y);
}
this.updateDrag(pointer);
+ if(this.bringToTop) {
+ this.sprite.group.bringToTop(this.sprite);
+ }
};
Input.prototype.stopDrag = /**
* Called by Pointer when drag is stopped on this Sprite. Should not usually be called directly.
@@ -4450,7 +4475,6 @@ var Phaser;
this.y = y;
this.z = -1;
this.group = null;
- // No dependencies
this.animations = new Phaser.Components.AnimationManager(this);
this.input = new Phaser.Components.Sprite.Input(this);
this.events = new Phaser.Components.Sprite.Events(this);
@@ -4472,6 +4496,10 @@ var Phaser;
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();
+ // Handy proxies
+ this.scale = this.transform.scale;
+ this.alpha = this.texture.alpha;
+ this.origin = this.transform.origin;
}
Object.defineProperty(Sprite.prototype, "rotation", {
get: /**
@@ -4608,8 +4636,8 @@ var Phaser;
* Clean up memory.
*/
function () {
- //this.input.destroy();
- };
+ this.input.destroy();
+ };
Sprite.prototype.kill = /**
* Handy for "killing" game objects.
* Default behavior is to flag them as nonexistent AND dead.
@@ -4750,62 +4778,6 @@ var Phaser;
this.getScreenXY(this._point, camera);
- return (objectScreenPos.x + objectOrGroup.width > this._point.x) && (objectScreenPos.x < this._point.x + this.width) &&
- (objectScreenPos.y + objectOrGroup.height > this._point.y) && (objectScreenPos.y < this._point.y + this.height);
- }
- */
- /**
- * Checks to see if this GameObject were located at the given position, would it overlap the GameObject or Group?
- * This is distinct from overlapsPoint(), which just checks that point, rather than taking the object's size into account.
- * WARNING: Currently tilemaps do NOT support screen space overlap checks!
- *
- * @param X {number} The X position you want to check. Pretends this object (the caller, not the parameter) is located here.
- * @param Y {number} The Y position you want to check. Pretends this object (the caller, not the parameter) is located here.
- * @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 two objects overlap.
- */
- /*
- static overlapsAt(X: number, Y: number, objectOrGroup, inScreenSpace: bool = false, camera: Camera = null): bool {
-
- if (objectOrGroup.isGroup)
- {
- var results: bool = false;
- var basic;
- var i: number = 0;
- var members = objectOrGroup.members;
-
- while (i < length)
- {
- if (this.overlapsAt(X, Y, members[i++], inScreenSpace, camera))
- {
- results = true;
- }
- }
-
- return results;
- }
-
- if (!inScreenSpace)
- {
- return (objectOrGroup.x + objectOrGroup.width > X) && (objectOrGroup.x < X + this.width) &&
- (objectOrGroup.y + objectOrGroup.height > Y) && (objectOrGroup.y < Y + this.height);
- }
-
- if (camera == null)
- {
- camera = this._game.camera;
- }
-
- var objectScreenPos: Point = objectOrGroup.getScreenXY(null, Camera);
-
- this._point.x = X - camera.scroll.x * this.transform.scrollFactor.x; //copied from getScreenXY()
- this._point.y = Y - camera.scroll.y * this.transform.scrollFactor.y;
- this._point.x += (this._point.x > 0) ? 0.0000001 : -0.0000001;
- this._point.y += (this._point.y > 0) ? 0.0000001 : -0.0000001;
-
return (objectScreenPos.x + objectOrGroup.width > this._point.x) && (objectScreenPos.x < this._point.x + this.width) &&
(objectScreenPos.y + objectOrGroup.height > this._point.y) && (objectScreenPos.y < this._point.y + this.height);
}
@@ -4825,52 +4797,32 @@ var Phaser;
if(sprite.transform.rotation == 0) {
return Phaser.RectangleUtils.contains(sprite.cameraView, x, y);
}
- //var ex: number = sprite.transform.upperRight.x - sprite.transform.upperLeft.x;
- //var ey: number = sprite.transform.upperRight.y - sprite.transform.upperLeft.y;
- //var fx: number = sprite.transform.bottomLeft.x - sprite.transform.upperLeft.x;
- //var fy: number = sprite.transform.bottomLeft.y - sprite.transform.upperLeft.y;
- //if ((x-ax)*ex+(y-ay)*ey<0.0) return false;
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-bx)*ex+(y-by)*ey>0.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-ax)*fx+(y-ay)*fy<0.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-dx)*fx+(y-dy)*fy>0.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 a point in 2D world space overlaps this GameObject.
+ * 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.
- * @param inScreenSpace {boolean} Whether to take scroll factors into account when checking for overlap.
- * @param camera {Camera} Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return Whether or not the point overlaps this object.
*/
- function overlapsPoint(sprite, point, inScreenSpace, camera) {
- if (typeof inScreenSpace === "undefined") { inScreenSpace = false; }
- if (typeof camera === "undefined") { camera = null; }
- if(!inScreenSpace) {
- return Phaser.RectangleUtils.containsPoint(sprite.body.bounds, point);
- //return (point.x > sprite.x) && (point.x < sprite.x + sprite.width) && (point.y > sprite.y) && (point.y < sprite.y + sprite.height);
- }
- if(camera == null) {
- camera = sprite.game.camera;
- }
- //var x: number = point.x - camera.scroll.x;
- //var y: number = point.y - camera.scroll.y;
- //this.getScreenXY(this._point, camera);
- //return (x > this._point.x) && (X < this._point.x + this.width) && (Y > this._point.y) && (Y < this._point.y + this.height);
- };
+ function overlapsPoint(sprite, point) {
+ return SpriteUtils.overlapsXY(sprite, point.x, point.y);
+ };
SpriteUtils.onScreen = /**
* Check and see if this object is currently on screen.
*
@@ -4940,15 +4892,6 @@ var Phaser;
sprite.body.position.x = x;
sprite.body.position.y = y;
};
- SpriteUtils.setOriginToCenter = function setOriginToCenter(sprite, fromFrameBounds, fromBody) {
- if (typeof fromFrameBounds === "undefined") { fromFrameBounds = true; }
- if (typeof fromBody === "undefined") { fromBody = false; }
- if(fromFrameBounds) {
- sprite.transform.origin.setTo(sprite.width / 2, sprite.height / 2);
- } else if(fromBody) {
- sprite.transform.origin.setTo(sprite.body.bounds.halfWidth, sprite.body.bounds.halfHeight);
- }
- };
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)
@@ -5535,7 +5478,15 @@ var Phaser;
this.members[this._i] = newObject;
return newObject;
};
- Group.prototype.swap = function (child1, child2, sort) {
+ 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;
@@ -5548,6 +5499,28 @@ var Phaser;
}
return true;
};
+ Group.prototype.bringToTop = function (child) {
+ // If child not in this group, or is already at the top of the group, return false
+ if(child.group.ID != this.ID || child.z == this._zCounter) {
+ return false;
+ }
+ this.sort();
+ // What's the z index of the top most child?
+ var tempZ = child.z;
+ var childIndex = this._zCounter;
+ this._i = 0;
+ while(this._i < this.length) {
+ this._member = this.members[this._i++];
+ if(this._i > childIndex) {
+ this._member.z--;
+ } else if(this._member.z == child.z) {
+ childIndex = this._i;
+ this._member.z = this._zCounter;
+ }
+ }
+ 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
@@ -6832,6 +6805,13 @@ var Phaser;
}
return null;
};
+ Cache.prototype.getImageKeys = function () {
+ var output = [];
+ for(var item in this._images) {
+ output.push(item);
+ }
+ return output;
+ };
Cache.prototype.destroy = /**
* Clean up cache memory.
*/
@@ -14951,7 +14931,7 @@ var Phaser;
var _highestRenderID = -1;
var _highestRenderObject = -1;
for(var i = 0; i < this.game.input.totalTrackedObjects; i++) {
- if(this.game.input.inputObjects[i].input.checkPointerOver(this) && this.game.input.inputObjects[i].renderOrderID > _highestRenderID) {
+ if(this.game.input.inputObjects[i] !== null && this.game.input.inputObjects[i].input.checkPointerOver(this) && this.game.input.inputObjects[i].renderOrderID > _highestRenderID) {
_highestRenderID = this.game.input.inputObjects[i].renderOrderID;
_highestRenderObject = i;
}
@@ -15010,7 +14990,7 @@ var Phaser;
this.game.input.currentPointers--;
}
for(var i = 0; i < this.game.input.totalTrackedObjects; i++) {
- if(this.game.input.inputObjects[i].input.enabled) {
+ if(this.game.input.inputObjects[i] !== null && this.game.input.inputObjects[i].input.enabled) {
this.game.input.inputObjects[i].input._releasedHandler(this);
}
}
@@ -16055,16 +16035,34 @@ var Phaser;
this.gestures.start();
this.mousePointer.active = true;
};
- Input.prototype.addGameObject = // Add Input Enabled array + add/remove methods and then iterate and update them during the main update
- // Clear down this array on State swap??? Maybe removed from it when Sprite is destroyed
+ Input.prototype.addGameObject = /**
+ * Adds a new game object to be tracked by the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method addGameObject
+ **/
function (object) {
- // Lots more checks here
+ // Find a spare slot
+ for(var i = 0; i < this.inputObjects.length; i++) {
+ if(this.inputObjects[i] == null) {
+ this.inputObjects[i] = object;
+ object.input.indexID = i;
+ this.totalTrackedObjects++;
+ return;
+ }
+ }
+ // If we got this far we need to push a new entry into the array
+ object.input.indexID = this.inputObjects.length;
this.inputObjects.push(object);
this.totalTrackedObjects++;
};
- Input.prototype.removeGameObject = function (object) {
- // TODO
- };
+ Input.prototype.removeGameObject = /**
+ * Removes a game object from the Input Manager. Called by the Sprite.Input component, should not usually be called directly.
+ * @method removeGameObject
+ **/
+ function (index) {
+ if(this.inputObjects[index]) {
+ this.inputObjects[index] = null;
+ }
+ };
Input.prototype.update = /**
* Updates the Input Manager. Called by the core Game loop.
* @method update