diff --git a/README.md b/README.md
index 980711ad7..ab2722df0 100644
--- a/README.md
+++ b/README.md
@@ -259,6 +259,8 @@ If you are an exceptional JavaScript developer and would like to join the Phaser
### New Features
* Emitter.emitParticle now has 4 new optional arguments: `x`, `y`, `key` and `frame`. These allow you to override whatever the Emitter default values may be and emit the particle from the given coordinates and with a new texture.
+* Group.resetChild is a new method that allows you to call both `child.reset` and/or `child.loadTexture` on the given child object. This is used internally by `getFirstDead` and similar, but is made public so you can use it as a group iteration callback. Note that the child must have public `reset` and `loadTexture` methods to be valid for the call.
+* Group.getFirstDead, Group.getFirstAlive and Group.getFirstExists all have new optional arguments: `createIfNull`, `x`, `y`, `key` and `frame`. If the method you call cannot find a matching child (i.e. getFirstDead cannot find any dead children) then the optional `createIfNull` allows you to instantly create a new child in the group using the position and texture arguments to do so. This allows you to always get a child back from the Group and remove the need to do null checks and Group inserts from your game code. The same arguments can also be used in a different way: if `createIfNull` is false AND you provide the extra arguments AND a child is found then it will be passed to the new `Group.resetChild` method. This allows you to retrieve a child from the Group and have it reset and instantly ready for use in your game without any extra code.
### Updates
diff --git a/src/core/Group.js b/src/core/Group.js
index 34f4c7502..8c6d7f6b6 100644
--- a/src/core/Group.js
+++ b/src/core/Group.js
@@ -465,13 +465,13 @@ Phaser.Group.prototype.getAt = function (index) {
/**
* Creates a new Phaser.Sprite object and adds it to the top of this group.
*
-* Use {@link #classType} to change the type of object creaded.
+* Use {@link #classType} to change the type of object created.
*
* @method Phaser.Group#create
* @param {number} x - The x coordinate to display the newly created Sprite at. The value is in relation to the group.x point.
* @param {number} y - The y coordinate to display the newly created Sprite at. The value is in relation to the group.y point.
-* @param {string} key - The Game.cache key of the image that this Sprite will use.
-* @param {integer|string} [frame] - If the Sprite image contains multiple frames you can specify which one to use here.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|Phaser.Video|PIXI.Texture} [key] - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData, Video or PIXI.Texture.
+* @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
* @param {boolean} [exists=true] - The default exists state of the Sprite.
* @return {DisplayObject} The child that was created: will be a {@link Phaser.Sprite} unless {@link #classType} has been changed.
*/
@@ -1773,47 +1773,134 @@ Phaser.Group.prototype.iterate = function (key, value, returnType, callback, cal
/**
* Get the first display object that exists, or doesn't exist.
+*
+* You can use the optional argument `createIfNull` to create a new Game Object if none matching your exists argument were found in this Group.
+*
+* It works by calling `Group.create` passing it the parameters given to this method, and returning the new child.
+*
+* If a child *was* found , `createIfNull` is `false` and you provided the additional arguments then the child
+* will be reset and/or have a new texture loaded on it. This is handled by `Group.resetChild`.
*
* @method Phaser.Group#getFirstExists
* @param {boolean} [exists=true] - If true, find the first existing child; otherwise find the first non-existing child.
-* @return {any} The first child, or null if none found.
+* @param {boolean} [createIfNull=false] - If `true` and no alive children are found a new one is created.
+* @param {number} [x] - The x coordinate to reset the child to. The value is in relation to the group.x point.
+* @param {number} [y] - The y coordinate to reset the child to. The value is in relation to the group.y point.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|Phaser.Video|PIXI.Texture} [key] - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData, Video or PIXI.Texture.
+* @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
+* @return {DisplayObject} The first child, or `null` if none found and `createIfNull` was false.
*/
-Phaser.Group.prototype.getFirstExists = function (exists) {
+Phaser.Group.prototype.getFirstExists = function (exists, createIfNull, x, y, key, frame) {
+
+ if (createIfNull === undefined) { createIfNull = false; }
if (typeof exists !== 'boolean')
{
exists = true;
}
- return this.iterate('exists', exists, Phaser.Group.RETURN_CHILD);
+ var child = this.iterate('exists', exists, Phaser.Group.RETURN_CHILD);
+
+ return (child === null && createIfNull) ? this.create(x, y, key, frame) : this.resetChild(child, x, y, key, frame);
};
/**
* Get the first child that is alive (`child.alive === true`).
*
-* This is handy for checking if everything has been wiped out, or choosing a squad leader, etc.
+* This is handy for choosing a squad leader, etc.
+*
+* You can use the optional argument `createIfNull` to create a new Game Object if no alive ones were found in this Group.
+*
+* It works by calling `Group.create` passing it the parameters given to this method, and returning the new child.
+*
+* If a child *was* found , `createIfNull` is `false` and you provided the additional arguments then the child
+* will be reset and/or have a new texture loaded on it. This is handled by `Group.resetChild`.
*
* @method Phaser.Group#getFirstAlive
-* @return {any} The first alive child, or null if none found.
+* @param {boolean} [createIfNull=false] - If `true` and no alive children are found a new one is created.
+* @param {number} [x] - The x coordinate to reset the child to. The value is in relation to the group.x point.
+* @param {number} [y] - The y coordinate to reset the child to. The value is in relation to the group.y point.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|Phaser.Video|PIXI.Texture} [key] - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData, Video or PIXI.Texture.
+* @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
+* @return {DisplayObject} The alive dead child, or `null` if none found and `createIfNull` was false.
*/
-Phaser.Group.prototype.getFirstAlive = function () {
+Phaser.Group.prototype.getFirstAlive = function (createIfNull, x, y, key, frame) {
- return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
+ if (createIfNull === undefined) { createIfNull = false; }
+
+ var child = this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
+
+ return (child === null && createIfNull) ? this.create(x, y, key, frame) : this.resetChild(child, x, y, key, frame);
};
/**
* Get the first child that is dead (`child.alive === false`).
*
-* This is handy for checking if everything has been wiped out, or choosing a squad leader, etc.
+* This is handy for checking if everything has been wiped out and adding to the pool as needed.
+*
+* You can use the optional argument `createIfNull` to create a new Game Object if no dead ones were found in this Group.
+*
+* It works by calling `Group.create` passing it the parameters given to this method, and returning the new child.
+*
+* If a child *was* found , `createIfNull` is `false` and you provided the additional arguments then the child
+* will be reset and/or have a new texture loaded on it. This is handled by `Group.resetChild`.
*
* @method Phaser.Group#getFirstDead
-* @return {any} The first dead child, or null if none found.
+* @param {boolean} [createIfNull=false] - If `true` and no dead children are found a new one is created.
+* @param {number} [x] - The x coordinate to reset the child to. The value is in relation to the group.x point.
+* @param {number} [y] - The y coordinate to reset the child to. The value is in relation to the group.y point.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|Phaser.Video|PIXI.Texture} [key] - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData, Video or PIXI.Texture.
+* @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
+* @return {DisplayObject} The first dead child, or `null` if none found and `createIfNull` was false.
*/
-Phaser.Group.prototype.getFirstDead = function () {
+Phaser.Group.prototype.getFirstDead = function (createIfNull, x, y, key, frame) {
- return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
+ if (createIfNull === undefined) { createIfNull = false; }
+
+ var child = this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
+
+ return (child === null && createIfNull) ? this.create(x, y, key, frame) : this.resetChild(child, x, y, key, frame);
+
+};
+
+/**
+* Takes a child and if the `x` and `y` arguments are given it calls `child.reset(x, y)` on it.
+*
+* If the `key` and optionally the `frame` arguments are given, it calls `child.loadTexture(key, frame)` on it.
+*
+* The two operations are separate. For example if you just wish to load a new texture then pass `null` as the x and y values.
+*
+* @method Phaser.Group#resetChild
+* @param {DisplayObject} child - The child to reset and/or load the texture on.
+* @param {number} [x] - The x coordinate to reset the child to. The value is in relation to the group.x point.
+* @param {number} [y] - The y coordinate to reset the child to. The value is in relation to the group.y point.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|Phaser.Video|PIXI.Texture} [key] - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData, Video or PIXI.Texture.
+* @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
+* @return {DisplayObject} The child that was reset: usually a {@link Phaser.Sprite}.
+*/
+Phaser.Group.prototype.resetChild = function (child, x, y, key, frame) {
+
+ if (child === null)
+ {
+ return null;
+ }
+
+ if (x === undefined) { x = null; }
+ if (y === undefined) { y = null; }
+
+ if (x !== null && y !== null)
+ {
+ child.reset(x, y);
+ }
+
+ if (key !== undefined)
+ {
+ child.loadTexture(key, frame);
+ }
+
+ return child;
};
diff --git a/typescript/phaser.d.ts b/typescript/phaser.d.ts
index 3de9d1347..08ef7f175 100644
--- a/typescript/phaser.d.ts
+++ b/typescript/phaser.d.ts
@@ -1,7 +1,7 @@
///
///
-// Type definitions for Phaser 2.4.4+ 2015-Aug-25
+// Type definitions for Phaser 2.4.4+ 2015-Aug-28
// Project: https://github.com/photonstorm/phaser
declare class Phaser {
@@ -1641,7 +1641,7 @@ declare module Phaser {
checkProperty(child: any, key: string[], value: any, force?: boolean): boolean;
countDead(): number;
countLiving(): number;
- create(x: number, y: number, key: string, frame?: any, exists?: boolean): any;
+ create(x: number, y: number, key?: string | Phaser.RenderTexture | Phaser.BitmapData | Phaser.Video | PIXI.Texture, frame?: string | number, exists?: boolean): any;
createMultiple(quantity: number, key: string, frame?: any, exists?: boolean): void;
customSort(sortHandler: Function, context?: any): void;
destroy(destroyChildren?: boolean, soft?: boolean): void;
@@ -1653,9 +1653,9 @@ declare module Phaser {
filter(predicate: Function, checkExists?: boolean): ArraySet;
getAt(index: number): PIXI.DisplayObject | number;
getBottom(): any;
- getFirstAlive(): any;
- getFirstDead(): any;
- getFirstExists(exists: boolean): any;
+ getFirstAlive(createIfNull?: boolean, x?: number, y?: number, key?: string | Phaser.RenderTexture | Phaser.BitmapData | Phaser.Video | PIXI.Texture, frame?: string | number): any;
+ getFirstDead(createIfNull?: boolean, x?: number, y?: number, key?: string | Phaser.RenderTexture | Phaser.BitmapData | Phaser.Video | PIXI.Texture, frame?: string | number): any;
+ getFirstExists(exists: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string | Phaser.RenderTexture | Phaser.BitmapData | Phaser.Video | PIXI.Texture, frame?: string | number): any;
getIndex(child: any): number;
getRandom(startIndex?: number, length?: number): any;
getTop(): any;
@@ -1674,6 +1674,7 @@ declare module Phaser {
removeBetween(startIndex: number, endIndex?: number, destroy?: boolean, silent?: boolean): void;
removeFromHash(child: PIXI.DisplayObject): boolean;
replace(oldChild: any, newChild: any): any;
+ resetChild(child: any, x?: number, y?: number, key?: string | Phaser.RenderTexture | Phaser.BitmapData | Phaser.Video | PIXI.Texture, frame?: string | number): any;
resetCursor(index?: number): any;
reverse(): void;
sendToBack(child: any): any;