Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

Working swapChild replacement


rich
 Share

Recommended Posts

Hi all,

 

This function is part of the new build of Phaser, but I know some of you are having trouble with this now so I figured I'd share it here. Basically it's a replacement for the swapChild method that is currently 'commented out' in the latest pixi.js build. This approach simply swaps nodes in the linked list, it doesn't tear it down then rebuild it again (no "removeChild / addChild" needed). It also works across containers, so you can swap two children from different containers. It also caters for next-door neighbour swaps, which is when the two nodes swapping are next/prev of each other.

 

Anyway it's working really nicely for me so hopefully you may like it too.

 

To use it simply pass a reference to your PIXI.Stage instance and the 2 children you wish to swap.

swapChildren: function (stage, child1, child2) {	if (child1 === child2 || !child1.parent || !child2.parent)	{		console.warn('You cannot swap a child with itself or swap un-parented children');		return;	}	//	Cache the values	var child1Prev = child1._iPrev;	var child1Next = child1._iNext;	var child2Prev = child2._iPrev;	var child2Next = child2._iNext;	var endNode = stage.last._iNext;	var currentNode = stage.first;			do		{		if (currentNode !== child1 && currentNode !== child2)		{			if (currentNode.first === child1)			{				currentNode.first = child2;			}			else if (currentNode.first === child2)			{				currentNode.first = child1;			}			if (currentNode.last === child1)			{				currentNode.last = child2;			}			else if (currentNode.last === child2)			{				currentNode.last = child1;			}		}		currentNode = currentNode._iNext;	}	while (currentNode != endNode)	if (child1._iNext == child2)	{		//	This is a downward (A to B) neighbour swap		child1._iNext = child2Next;		child1._iPrev = child2;		child2._iNext = child1;		child2._iPrev = child1Prev;		if (child1Prev) { child1Prev._iNext = child2; }		if (child2Next) { child2Next._iPrev = child1; }	}	else if (child2._iNext == child1)	{		//	This is an upward (B to A) neighbour swap		child1._iNext = child2;		child1._iPrev = child2Prev;		child2._iNext = child1Next;		child2._iPrev = child1;		if (child2Prev) { child2Prev._iNext = child1; }		if (child1Next) { child2Next._iPrev = child2; }	}	else	{		//	Children are far apart		child1._iNext = child2Next;		child1._iPrev = child2Prev;		child2._iNext = child1Next;		child2._iPrev = child1Prev;		if (child1Prev) { child1Prev._iNext = child2; }		if (child1Next) { child1Next._iPrev = child2; }		if (child2Prev) { child2Prev._iNext = child1; }		if (child2Next) { child2Next._iPrev = child1; }	}}
Link to comment
Share on other sites

One thing to add is a flag to mention that the texture has updated - this will make the webGL Renderer do a little check to see if the batchs are still valid

 

Ah yes - could you show me what flag to add please? :)

 

Also if there is a way to obtain 'stage' without needing to explicitly pass it that would be good, ideally a way of getting that without traversing the entire list backwards?

Link to comment
Share on other sites

  • 3 weeks later...

I have a question about this, i have a layer of generated trees in a displayObjectContainer, i wish to swap their depths based on their scale (large trees > small trees) but just swapping isn't enough: I need their index to see if one is above the other. Since the display object (?) properties ._iPrev and ._iNext are unfamiliar to me, can i use these properties to find out if one tree is higher in the display list than another? or for that matter, a modified version of your function? :>

 

Working version: http://www.powergeek.nl/proj/mongento/versions/5/ (no preloading yet, wait for trees to show :> )

Link to comment
Share on other sites

  • 1 month later...

Hmm. I wanted to use this method any time I need to change the draw-order (y coordinate check).
But infortunatly the code freeze up the whole browser. No error Messages. Nothing. Some debugging brang up an inv loop.

 

Simply passed the pixi stage object and the two sprites that need to flip.

 

 

Just a naiv thought but, would it be possible to use the z-axis to set this kind of order?

Link to comment
Share on other sites

Ah yes I forgot I had posted it here. There is a bug in the above code snippet. Here is a fully working version:

	/**	* Swaps the position of two children in this Group. Both children must be 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.	* @param {*} child2 - The second child to swap.    * @return {boolean} True if the swap was successful, otherwise false.	*/	swap: function (child1, child2) {		if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)		{			return false;		}		//	Cache the values		var child1Prev = child1._iPrev;		var child1Next = child1._iNext;		var child2Prev = child2._iPrev;		var child2Next = child2._iNext;		var endNode = this._container.last._iNext;		var currentNode = this.game.stage._stage;					do		{			if (currentNode !== child1 && currentNode !== child2)			{				if (currentNode.first === child1)				{					currentNode.first = child2;				}				else if (currentNode.first === child2)				{					currentNode.first = child1;				}				if (currentNode.last === child1)				{					currentNode.last = child2;				}				else if (currentNode.last === child2)				{					currentNode.last = child1;				}			}			currentNode = currentNode._iNext;		}		while (currentNode != endNode)		if (child1._iNext == child2)		{			//	This is a downward (A to B) neighbour swap			child1._iNext = child2Next;			child1._iPrev = child2;			child2._iNext = child1;			child2._iPrev = child1Prev;			if (child1Prev) { child1Prev._iNext = child2; }			if (child2Next) { child2Next._iPrev = child1; }			if (child1.__renderGroup)			{				child1.__renderGroup.updateTexture(child1);			}			if (child2.__renderGroup)			{				child2.__renderGroup.updateTexture(child2);			}			return true;		}		else if (child2._iNext == child1)		{			//	This is an upward (B to A) neighbour swap			child1._iNext = child2;			child1._iPrev = child2Prev;			child2._iNext = child1Next;			child2._iPrev = child1;			if (child2Prev) { child2Prev._iNext = child1; }			if (child1Next) { child1Next._iPrev = child2; }			if (child1.__renderGroup)			{				child1.__renderGroup.updateTexture(child1);			}			if (child2.__renderGroup)			{				child2.__renderGroup.updateTexture(child2);			}			return true;		}		else		{			//	Children are far apart			child1._iNext = child2Next;			child1._iPrev = child2Prev;			child2._iNext = child1Next;			child2._iPrev = child1Prev;			if (child1Prev) { child1Prev._iNext = child2; }			if (child1Next) { child1Next._iPrev = child2; }			if (child2Prev) { child2Prev._iNext = child1; }			if (child2Next) { child2Next._iPrev = child1; }			if (child1.__renderGroup)			{				child1.__renderGroup.updateTexture(child1);			}			if (child2.__renderGroup)			{				child2.__renderGroup.updateTexture(child2);			}			return true;		}		return false;			},
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...