rich Posted September 5, 2013 Share Posted September 5, 2013 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 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; } }} Qqwy 1 Quote Link to comment Share on other sites More sharing options...
xerver Posted September 5, 2013 Share Posted September 5, 2013 No pr? Quote Link to comment Share on other sites More sharing options...
Mat Groves Posted September 5, 2013 Share Posted September 5, 2013 Nice one Rich! This will work like a champOne 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 Thanks for this! Quote Link to comment Share on other sites More sharing options...
rich Posted September 5, 2013 Author Share Posted September 5, 2013 No because it doesn't fit your current API design (the need for the stage reference). I am happy to submit one but I tend to try not to if it changes documented functions Quote Link to comment Share on other sites More sharing options...
rich Posted September 5, 2013 Author Share Posted September 5, 2013 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? Quote Link to comment Share on other sites More sharing options...
Mat Groves Posted September 5, 2013 Share Posted September 5, 2013 Yup, every element has a "root" object which will mostly be stage unless its being rendered to a render texture. Quote Link to comment Share on other sites More sharing options...
michahell Posted September 23, 2013 Share Posted September 23, 2013 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 :> ) Quote Link to comment Share on other sites More sharing options...
rich Posted September 23, 2013 Author Share Posted September 23, 2013 iPrev and iNext (if set) are the previous and next nodes in the linked list. So whatever iPrev contains was rendered before the current node, and whatever iNext contains is going to be rendered next (assuming visible true, etc). Quote Link to comment Share on other sites More sharing options...
tharo Posted November 19, 2013 Share Posted November 19, 2013 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? Quote Link to comment Share on other sites More sharing options...
rich Posted November 20, 2013 Author Share Posted November 20, 2013 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 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; }, tharo 1 Quote Link to comment Share on other sites More sharing options...
tharo Posted November 20, 2013 Share Posted November 20, 2013 I love you :3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.