mirror of
https://github.com/wassname/phaser.git
synced 2026-06-27 16:10:15 +08:00
Tracked down an evil bug in Group.swap that caused the linked list to get corrupted in an upward (B to A) neighbour swap.
This commit is contained in:
@@ -46,6 +46,7 @@ Version 1.1.3 - in build
|
||||
* New: StageScaleMode.forceOrientation allows you to lock your game to one orientation and display a Sprite (i.e. a "please rotate" screen) when incorrect.
|
||||
* New: World.visible boolean added, toggles rendering of the world on/off entirely.
|
||||
* New: Polygon class & drawPolygon method added to Graphics (thanks rjimenezda)
|
||||
* New: Added Group.iterate, a powerful way to count or return child that match a certain criteria. Refactored Group to use iterate, lots of repeated code cut.
|
||||
* Fixed: Mouse.stop now uses the true useCapture, which means the event listeners stop listening correctly (thanks beeglebug)
|
||||
* Fixed: Input Keyboard example fix (thanks Atrodilla)
|
||||
* Updated: ArcadePhysics.updateMotion applies the dt to the velocity calculations as well as position now (thanks jcs)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.image('phaser', 'assets/sprites/phaser-dude.png');
|
||||
game.load.spritesheet('veggies', 'assets/sprites/fruitnveg32wh37.png', 32, 32);
|
||||
|
||||
}
|
||||
|
||||
var sprite;
|
||||
var group;
|
||||
var oldY = 0;
|
||||
|
||||
function create() {
|
||||
|
||||
game.stage.backgroundColor = '#2d2d2d';
|
||||
|
||||
// sprite = game.add.sprite(32, 200, 'phaser');
|
||||
// sprite.name = 'phaser-dude';
|
||||
|
||||
group = game.add.group();
|
||||
|
||||
sprite = group.create(300, 200, 'phaser');
|
||||
sprite.name = 'phaser-dude';
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var c = group.create(100 + Math.random() * 700, game.world.randomY, 'veggies', game.rnd.integerInRange(0, 36));
|
||||
c.name = 'veg' + i;
|
||||
}
|
||||
|
||||
game.input.onUp.add(sortGroup, this);
|
||||
game.input.keyboard.addKeyCapture([ Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.UP, Phaser.Keyboard.DOWN ]);
|
||||
|
||||
}
|
||||
|
||||
function sortGroup () {
|
||||
|
||||
console.log('%c ', 'background: #efefef');
|
||||
group.sort();
|
||||
group.dump(false);
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
sprite.body.velocity.x = 0;
|
||||
sprite.body.velocity.y = 0;
|
||||
|
||||
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
|
||||
{
|
||||
sprite.body.velocity.x = -200;
|
||||
}
|
||||
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
|
||||
{
|
||||
sprite.body.velocity.x = 200;
|
||||
}
|
||||
|
||||
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
|
||||
{
|
||||
sprite.body.velocity.y = -200;
|
||||
}
|
||||
else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
|
||||
{
|
||||
sprite.body.velocity.y = 200;
|
||||
}
|
||||
|
||||
if (sprite.y !== oldY)
|
||||
{
|
||||
// console.log('sorted');
|
||||
// group.sort();
|
||||
// oldY = sprite.y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
// game.debug.renderText(group.cursor.name, 32, 32);
|
||||
// game.debug.renderInputInfo(32, 32);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.image('phaser', 'assets/sprites/phaser-dude.png');
|
||||
game.load.spritesheet('veggies', 'assets/sprites/fruitnveg32wh37.png', 32, 32);
|
||||
|
||||
}
|
||||
|
||||
var group;
|
||||
var start = false;
|
||||
var swapCount = 0;
|
||||
var time = 0;
|
||||
var test = 0;
|
||||
|
||||
function create() {
|
||||
|
||||
game.stage.backgroundColor = '#2d2d2d';
|
||||
|
||||
group = game.add.group();
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var c = group.create(100 + Math.random() * 700, game.world.randomY, 'veggies', game.rnd.integerInRange(0, 36));
|
||||
c.name = 'veg' + i;
|
||||
}
|
||||
|
||||
test = group.length;
|
||||
|
||||
game.input.onUp.add(toggleSwap, this);
|
||||
|
||||
}
|
||||
|
||||
function toggleSwap () {
|
||||
|
||||
if (start)
|
||||
{
|
||||
start = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
if (start && game.time.now > time)
|
||||
{
|
||||
var a = group.getRandom();
|
||||
var b = group.getRandom();
|
||||
|
||||
if (a.name !== b.name)
|
||||
{
|
||||
console.log('************************ NEW ROUND *********************');
|
||||
group.dump(true);
|
||||
console.log('Group Size: ' + group.length);
|
||||
group.swap(a, b);
|
||||
swapCount++;
|
||||
|
||||
if (group.length !== test)
|
||||
{
|
||||
start = false;
|
||||
console.log('************************ SHIT *********************');
|
||||
group.dump(true);
|
||||
console.log('************************ SHIT *********************');
|
||||
}
|
||||
|
||||
if (group.validate() == false)
|
||||
{
|
||||
start = false;
|
||||
console.log('************************ VALIDATE FAIL *********************');
|
||||
group.dump(true);
|
||||
console.log('************************ VALIDATE FAIL *********************');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
time = game.time.now + 100;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.renderText('Swap: ' + swapCount, 32, 32);
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ BasicGame.MainMenu.prototype = {
|
||||
|
||||
create: function () {
|
||||
|
||||
// We've already preloaded our assets, so let's kick right into the Main Menu itself
|
||||
// We've already preloaded our assets, so let's kick right into the Main Menu itself.
|
||||
// Here all we're doing is playing some music and adding a picture and button
|
||||
// Naturally I expect you to do something significantly better :)
|
||||
|
||||
|
||||
@@ -17,12 +17,13 @@ BasicGame.Preloader.prototype = {
|
||||
this.background = this.add.sprite(0, 0, 'preloaderBackground');
|
||||
this.preloadBar = this.add.sprite(300, 400, 'preloaderBar');
|
||||
|
||||
// This sets the preloadBar sprite as a loader sprite, basically
|
||||
// what that does is automatically crop the sprite from 0 to full-width
|
||||
// This sets the preloadBar sprite as a loader sprite.
|
||||
// What that does is automatically crop the sprite from 0 to full-width
|
||||
// as the files below are loaded in.
|
||||
this.load.setPreloadSprite(this.preloadBar);
|
||||
|
||||
// Here we load most of the assets our game needs
|
||||
// Here we load the rest of the assets our game needs.
|
||||
// As this is just a Project Template I've not provided these assets, swap them for your own.
|
||||
this.load.image('titlepage', 'images/title.jpg');
|
||||
this.load.atlas('playButton', 'images/play_button.png', 'images/play_button.json');
|
||||
this.load.audio('titleMusic', ['audio/main_menu.mp3']);
|
||||
@@ -33,7 +34,7 @@ BasicGame.Preloader.prototype = {
|
||||
|
||||
create: function () {
|
||||
|
||||
// Once the load has finished we disable the crop because we're going to sit in the update loop for a short while
|
||||
// Once the load has finished we disable the crop because we're going to sit in the update loop for a short while as the music decodes
|
||||
this.preloadBar.cropEnabled = false;
|
||||
|
||||
},
|
||||
@@ -51,7 +52,7 @@ BasicGame.Preloader.prototype = {
|
||||
|
||||
if (this.cache.isSoundDecoded('titleMusic') && this.ready == false)
|
||||
{
|
||||
this.ready = false;
|
||||
this.ready = true;
|
||||
this.game.state.start('MainMenu');
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Phaser Basic Project Template</title>
|
||||
<script src="phaser.min.js"></script>
|
||||
<script src="Boot.js"></script>
|
||||
<script src="Preloader.js"></script>
|
||||
<script src="MainMenu.js"></script>
|
||||
@@ -17,7 +18,7 @@
|
||||
window.onload = function() {
|
||||
|
||||
// Create your Phaser game and inject it into the gameContainer div.
|
||||
// We did it in a window.onload event, but you can do it anywhere (requireJS load, anonymous function, jQuery dom ready, etc - whatever floats your boat)
|
||||
// We did it in a window.onload event, but you can do it anywhere (requireJS load, anonymous function, jQuery dom ready, - whatever floats your boat)
|
||||
var game = new Phaser.Game(1024, 768, Phaser.AUTO, 'gameContainer');
|
||||
|
||||
// Add the States your game has.
|
||||
|
||||
@@ -425,6 +425,8 @@ Phaser.Game.prototype = {
|
||||
if (this._paused)
|
||||
{
|
||||
this.renderer.render(this.stage._stage);
|
||||
this.plugins.render();
|
||||
this.state.render();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+313
-124
@@ -89,8 +89,50 @@ Phaser.Group = function (game, parent, name, useStage) {
|
||||
*/
|
||||
this.cursor = null;
|
||||
|
||||
/**
|
||||
* Helper for sort.
|
||||
*/
|
||||
this._sortIndex = '';
|
||||
|
||||
/**
|
||||
* Helper for sort.
|
||||
*/
|
||||
this._sortOrder = 0;
|
||||
|
||||
this._sortCache = [];
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Group.RETURN_NONE = 0;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Group.RETURN_TOTAL = 1;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Group.RETURN_CHILD = 2;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Group.SORT_ASCENDING = -1;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Group.SORT_DESCENDING = 1;
|
||||
|
||||
Phaser.Group.prototype = {
|
||||
|
||||
/**
|
||||
@@ -303,8 +345,37 @@ Phaser.Group.prototype = {
|
||||
|
||||
},
|
||||
|
||||
childTest: function (prefix, child) {
|
||||
|
||||
var s = prefix + ' next: ';
|
||||
|
||||
if (child._iNext)
|
||||
{
|
||||
s = s + child._iNext.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = s + '-null-';
|
||||
}
|
||||
|
||||
s = s + ' ' + prefix + ' prev: ';
|
||||
|
||||
if (child._iPrev)
|
||||
{
|
||||
s = s + child._iPrev.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = s + '-null-';
|
||||
}
|
||||
|
||||
console.log(s);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Swaps the position of two children in this Group.
|
||||
* You cannot swap a child with itself, or swap un-parented children, doing so will return false.
|
||||
*
|
||||
* @method Phaser.Group#swap
|
||||
* @param {*} child1 - The first child to swap.
|
||||
@@ -313,9 +384,11 @@ Phaser.Group.prototype = {
|
||||
*/
|
||||
swap: function (child1, child2) {
|
||||
|
||||
console.log('starting swap', child1.name, 'with', child2.name);
|
||||
|
||||
if (child1 === child2 || !child1.parent || !child2.parent)
|
||||
{
|
||||
console.warn('You cannot swap a child with itself or swap un-parented children');
|
||||
console.log('cannot swap these')
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -325,8 +398,17 @@ Phaser.Group.prototype = {
|
||||
var child2Prev = child2._iPrev;
|
||||
var child2Next = child2._iNext;
|
||||
|
||||
var endNode = this._container.last._iNext;
|
||||
// var endNode = this._container.last._iNext;
|
||||
var endNode = this._container.last;
|
||||
var currentNode = this.game.stage._stage;
|
||||
|
||||
console.log('start do while. start node: ', currentNode.name);
|
||||
console.log(typeof endNode);
|
||||
|
||||
if (endNode)
|
||||
{
|
||||
console.log('end node: ', endNode.name);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
@@ -355,9 +437,15 @@ Phaser.Group.prototype = {
|
||||
}
|
||||
while (currentNode != endNode)
|
||||
|
||||
console.log('end do while');
|
||||
|
||||
if (child1._iNext == child2)
|
||||
{
|
||||
// This is a downward (A to B) neighbour swap
|
||||
console.log('downward A to B');
|
||||
this.childTest('1', child1);
|
||||
this.childTest('2', child2);
|
||||
|
||||
child1._iNext = child2Next;
|
||||
child1._iPrev = child2;
|
||||
child2._iNext = child1;
|
||||
@@ -381,13 +469,17 @@ Phaser.Group.prototype = {
|
||||
else if (child2._iNext == child1)
|
||||
{
|
||||
// This is an upward (B to A) neighbour swap
|
||||
console.log('upward B to A');
|
||||
this.childTest('1', child1);
|
||||
this.childTest('2', child2);
|
||||
|
||||
child1._iNext = child2;
|
||||
child1._iPrev = child2Prev;
|
||||
child2._iNext = child1Next;
|
||||
child2._iPrev = child1;
|
||||
|
||||
if (child2Prev) { child2Prev._iNext = child1; }
|
||||
if (child1Next) { child2Next._iPrev = child2; }
|
||||
if (child1Next) { child1Next._iPrev = child2; }
|
||||
|
||||
if (child1.__renderGroup)
|
||||
{
|
||||
@@ -404,6 +496,11 @@ Phaser.Group.prototype = {
|
||||
else
|
||||
{
|
||||
// Children are far apart
|
||||
console.log('far apart A to B');
|
||||
|
||||
this.childTest('1', child1);
|
||||
this.childTest('2', child2);
|
||||
|
||||
child1._iNext = child2Next;
|
||||
child1._iPrev = child2Prev;
|
||||
child2._iNext = child1Next;
|
||||
@@ -754,7 +851,7 @@ Phaser.Group.prototype = {
|
||||
|
||||
/**
|
||||
* Calls a function on all of the children regardless if they are dead or alive (see callAllExists if you need control over that)
|
||||
* After the method parameter you can add as many extra parameters as you like, which will all be passed to the child.
|
||||
* After the method parameter and context you can add as many extra parameters as you like, which will all be passed to the child.
|
||||
*
|
||||
* @method Phaser.Group#callAll
|
||||
* @param {string} method - A string containing the name of the function that will be called. The function must exist on the child.
|
||||
@@ -860,6 +957,24 @@ Phaser.Group.prototype = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Allows you to call your own function on each alive member of this Group (where child.alive=true). You must pass the callback and context in which it will run.
|
||||
* You can add as many parameters as you like, which will all be passed to the callback along with the child.
|
||||
* For example: Group.forEachAlive(causeDamage, this, 500)
|
||||
*
|
||||
* @method Phaser.Group#forEachAlive
|
||||
* @param {function} callback - The function that will be called. Each child of the Group will be passed to it as its first parameter.
|
||||
* @param {Object} callbackContext - The context in which the function should be called (usually 'this').
|
||||
*/
|
||||
forEachExists: function (callback, callbackContext) {
|
||||
|
||||
var args = Array.prototype.splice.call(arguments, 2);
|
||||
args.unshift(null);
|
||||
|
||||
this.iterate('exists', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Allows you to call your own function on each alive member of this Group (where child.alive=true). You must pass the callback and context in which it will run.
|
||||
* You can add as many parameters as you like, which will all be passed to the callback along with the child.
|
||||
@@ -874,23 +989,7 @@ Phaser.Group.prototype = {
|
||||
var args = Array.prototype.splice.call(arguments, 2);
|
||||
args.unshift(null);
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (currentNode.alive)
|
||||
{
|
||||
args[0] = currentNode;
|
||||
callback.apply(callbackContext, args);
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
|
||||
}
|
||||
this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
|
||||
|
||||
},
|
||||
|
||||
@@ -908,23 +1007,159 @@ Phaser.Group.prototype = {
|
||||
var args = Array.prototype.splice.call(arguments, 2);
|
||||
args.unshift(null);
|
||||
|
||||
this.iterate('alive', false, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
* <code>myGroup.sort("y",Group.ASCENDING)</code> at the bottom of your
|
||||
* <code>State.update()</code> override. To sort all existing objects after
|
||||
* a big explosion or bomb attack, you might call <code>myGroup.sort("exists",Group.DESCENDING)</code>.
|
||||
*
|
||||
* @param {string} index The <code>string</code> name of the member variable you want to sort on. Default value is "z".
|
||||
* @param {number} order A <code>Group</code> constant that defines the sort order. Possible values are <code>Group.ASCENDING</code> and <code>Group.DESCENDING</code>. Default value is <code>Group.ASCENDING</code>.
|
||||
*/
|
||||
sort: function (index, order) {
|
||||
|
||||
if (typeof index === 'undefined') { index = 'y'; }
|
||||
if (typeof order === 'undefined') { order = Phaser.Group.SORT_ASCENDING; }
|
||||
|
||||
this._sortIndex = index;
|
||||
this._sortOrder = order;
|
||||
this._sortCache = this._container.children.slice();
|
||||
|
||||
console.log('-vvv--------------------------------------------------------------------------------');
|
||||
|
||||
for (var i = 0; i < this._sortCache.length; i++)
|
||||
{
|
||||
console.log(i + ' = ' + this._sortCache[i].name + ' at y: ' + this._sortCache[i].y);
|
||||
}
|
||||
|
||||
console.log('---------------------------------------------------------------------------------');
|
||||
|
||||
this._sortCache.sort(this.sortHandler.bind(this));
|
||||
|
||||
for (var i = 0; i < this._sortCache.length; i++)
|
||||
{
|
||||
console.log(i + ' = ' + this._sortCache[i].name + ' at y: ' + this._sortCache[i].y);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this._sortCache.length; i++)
|
||||
{
|
||||
if (this._container.children[i] !== this._sortCache[i])
|
||||
{
|
||||
console.log('swapped:', this._container.children[i].name,'with',this._sortCache[i].name);
|
||||
this.swap(this._container.children[i], this._sortCache[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Now put it back again
|
||||
this._container.children = this._sortCache.slice();
|
||||
|
||||
this._container.updateTransform();
|
||||
|
||||
console.log('-^^^--------------------------------------------------------------------------------');
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
sortHandler: function (obj1, obj2) {
|
||||
|
||||
if (!obj1 || !obj2)
|
||||
{
|
||||
// console.log('null objects in sort', obj1, obj2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// number only test
|
||||
// return obj1[this._sortIndex] - obj2[this._sortIndex];
|
||||
|
||||
if (obj1[this._sortIndex] < obj2[this._sortIndex])
|
||||
{
|
||||
// console.log('1 < 2');
|
||||
return this._sortOrder;
|
||||
}
|
||||
else if (obj1[this._sortIndex] > obj2[this._sortIndex])
|
||||
{
|
||||
// console.log('1 > 2');
|
||||
return -this._sortOrder;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterates over the children of the Group. When a child has a property matching key that equals the given value, it is considered as a match.
|
||||
* Matched children can be sent to the optional callback, or simply returned or counted.
|
||||
* You can add as many callback parameters as you like, which will all be passed to the callback along with the child, after the callbackContext parameter.
|
||||
*
|
||||
* @method Phaser.Group#iterate
|
||||
* @param {string} key - The child property to check, i.e. 'exists', 'alive', 'health'
|
||||
* @param {any} value - If child.key === this value it will be considered a match. Note that a strict comparison is used.
|
||||
* @param {number} returnType - How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD.
|
||||
* @param {function} [callback=null] - Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter.
|
||||
* @param {Object} [callbackContext] - The context in which the function should be called (usually 'this').
|
||||
*/
|
||||
iterate: function (key, value, returnType, callback, callbackContext, args) {
|
||||
|
||||
if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (typeof callback === 'undefined')
|
||||
{
|
||||
callback = false;
|
||||
}
|
||||
|
||||
var total = 0;
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (currentNode.alive == false)
|
||||
if (currentNode[key] === value)
|
||||
{
|
||||
args[0] = currentNode;
|
||||
callback.apply(callbackContext, args);
|
||||
total++;
|
||||
|
||||
if (callback)
|
||||
{
|
||||
args[0] = currentNode;
|
||||
callback.apply(callbackContext, args);
|
||||
}
|
||||
|
||||
if (returnType == Phaser.Group.RETURN_CHILD)
|
||||
{
|
||||
return currentNode;
|
||||
}
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
|
||||
}
|
||||
|
||||
if (returnType == Phaser.Group.RETURN_TOTAL)
|
||||
{
|
||||
return total;
|
||||
}
|
||||
else if (returnType == Phaser.Group.RETURN_CHILD)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -941,23 +1176,7 @@ Phaser.Group.prototype = {
|
||||
state = true;
|
||||
}
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (currentNode.exists === state)
|
||||
{
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
}
|
||||
|
||||
return null;
|
||||
return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
|
||||
|
||||
},
|
||||
|
||||
@@ -970,23 +1189,7 @@ Phaser.Group.prototype = {
|
||||
*/
|
||||
getFirstAlive: function () {
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (currentNode.alive)
|
||||
{
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
}
|
||||
|
||||
return null;
|
||||
return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
|
||||
|
||||
},
|
||||
|
||||
@@ -999,23 +1202,7 @@ Phaser.Group.prototype = {
|
||||
*/
|
||||
getFirstDead: function () {
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (!currentNode.alive)
|
||||
{
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
}
|
||||
|
||||
return null;
|
||||
return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
|
||||
|
||||
},
|
||||
|
||||
@@ -1027,29 +1214,7 @@ Phaser.Group.prototype = {
|
||||
*/
|
||||
countLiving: function () {
|
||||
|
||||
var total = 0;
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (currentNode.alive)
|
||||
{
|
||||
total++;
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = -1;
|
||||
}
|
||||
|
||||
return total;
|
||||
return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
|
||||
|
||||
},
|
||||
|
||||
@@ -1061,29 +1226,7 @@ Phaser.Group.prototype = {
|
||||
*/
|
||||
countDead: function () {
|
||||
|
||||
var total = 0;
|
||||
|
||||
if (this._container.children.length > 0 && this._container.first._iNext)
|
||||
{
|
||||
var currentNode = this._container.first._iNext;
|
||||
|
||||
do
|
||||
{
|
||||
if (!currentNode.alive)
|
||||
{
|
||||
total++;
|
||||
}
|
||||
|
||||
currentNode = currentNode._iNext;
|
||||
}
|
||||
while (currentNode != this._container.last._iNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
total = -1;
|
||||
}
|
||||
|
||||
return total;
|
||||
return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
|
||||
|
||||
},
|
||||
|
||||
@@ -1228,6 +1371,48 @@ Phaser.Group.prototype = {
|
||||
|
||||
},
|
||||
|
||||
validate: function () {
|
||||
|
||||
var testObject = this.game.stage._stage.last._iNext;
|
||||
var displayObject = this.game.stage._stage;
|
||||
var nextObject = null;
|
||||
var prevObject = null;
|
||||
var count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
// check next
|
||||
if (displayObject !== nextObject)
|
||||
{
|
||||
console.log('check next fail');
|
||||
return false;
|
||||
}
|
||||
|
||||
// check previous
|
||||
if (displayObject._iPrev !== prevObject)
|
||||
{
|
||||
console.log('check previous fail');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the next object
|
||||
nextObject = displayObject._iNext;
|
||||
prevObject = displayObject;
|
||||
|
||||
displayObject = displayObject._iNext;
|
||||
|
||||
count++;
|
||||
|
||||
}
|
||||
while(displayObject != testObject)
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.
|
||||
*
|
||||
@@ -1252,11 +1437,13 @@ Phaser.Group.prototype = {
|
||||
if (full)
|
||||
{
|
||||
var testObject = this.game.stage._stage.last._iNext;
|
||||
// var testObject = this.game.stage._stage.last;
|
||||
var displayObject = this.game.stage._stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
var testObject = this._container.last._iNext;
|
||||
// var testObject = this._container.last;
|
||||
var displayObject = this._container;
|
||||
}
|
||||
|
||||
@@ -1334,7 +1521,8 @@ Phaser.Group.prototype = {
|
||||
Object.defineProperty(Phaser.Group.prototype, "total", {
|
||||
|
||||
get: function () {
|
||||
return this._container.children.length;
|
||||
return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
|
||||
// return this._container.children.length;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1347,7 +1535,8 @@ Object.defineProperty(Phaser.Group.prototype, "total", {
|
||||
Object.defineProperty(Phaser.Group.prototype, "length", {
|
||||
|
||||
get: function () {
|
||||
return this._container.children.length;
|
||||
return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
|
||||
// return this._container.children.length;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user