Just normal animation aims, nothing G1 couldn’t handle in its sleep. Will report back if something isn’t working as it should. But the reality is that G2 now requires more layers of code to achieve the exact same thing as G1 did in reference to nested groups. Struggling to see how this is an improvement to the api.
Hi @kilopop,
If you have a test example, please share. I haven’t seen much yet that anchor points can’t handle, and one vast improvement over reference points is the ability to set the anchor around any point on the object, not just 8 edge points and a center point.
Brent
My point was nested groups with “anchorChildren = true” was never intended to be supported and is not tested. The property was added to support containers, which are a form of groups. Graphics 2.0 groups are not 100% compatible with Graphics 1.0 groups.
You’re saying effectively that you can’t see any application for requiring anchors in a group and the implementation of it now in Corona is an after thought addition, the use of which leading to unpredictable outcomes?
But you have to allow for anchors in groups, otherwise how can you perform animation on groups that need to define where the anchor is such as rotation, scale and move (to exact coordinates rather than self.x=self.x+z)?
What is your suggestion for animating groups without using anchors?
I didn’t state that I can’t see any need for using anchors on groups. It clearly does work as shown in the groups guide. Where are you encountering issues that can’t seemingly be overcome?
Groups with anchorPoints is allowed and was designed into Graphics 2.0. Setting the anchorChildren property for nested groups was not intended and not recommended. I never said groups with anchorPoints was an afterthought.
Ok sure, more specifically you are saying nested Groups were never intended to be supported. That statement in itself is very concerning as it sounds like you’re starting to limit who uses Corona and how.
Here’s a quick test of nested groups. It creates a simple vehicle with wheels rotating which are a part of a vehicle group which is moving across the screen, landscape, h_1536, w_2048. Of course there are plenty of ways to make this car and move it, that’s not the point of this comparison but rather to show how nested groups are not working. Firstly G1:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local gp\_carBody = display.newGroup() local gp\_wheel1 = display.newGroup() local gp\_wheel2 = display.newGroup() local gp\_car = display.newGroup() -- body positioning local body = display.newRect( 1098, 808, 748, 228 ) body:setFillColor( 255, 255, 255 ) -- top positioning local top = display.newRect( 1315, 628, 276, 260 ) top:setFillColor( 255, 255, 255 ) -- tyre1 positioning local tyre1 = display.newCircle( 1265, 1041, 75 ) tyre1:setFillColor( 3, 145, 222 ) -- cap1 positioning local cap1 = display.newCircle( 1265, 1041, 53 ) cap1:setFillColor( 255, 255, 255 ) -- tyre2 positioning local tyre2 = display.newCircle( 1689, 1041, 75 ) tyre2:setFillColor( 3, 145, 222 ) -- cap2 positioning local cap2 = display.newCircle( 1689, 1041, 53 ) cap2:setFillColor( 255, 255, 255 ) -- Organise Groups gp\_carBody:insert(body) gp\_carBody:insert(top) gp\_wheel1:insert(tyre1) gp\_wheel1:insert(cap1) gp\_wheel1:setReferencePoint( display.CenterReferencePoint ) gp\_wheel1.xScale = 0.5 gp\_wheel2:insert(tyre2) gp\_wheel2:insert(cap2) gp\_wheel2:setReferencePoint( display.CenterReferencePoint ) gp\_wheel2.yScale = 0.5 gp\_car:insert(gp\_carBody) gp\_car:insert(gp\_wheel1) gp\_car:insert(gp\_wheel2) -- animation transition.to (gp\_car, { time = 4000, x = -1000 } ) transition.to (gp\_wheel1, { time = 500, rotation = -360, iterations=8} ) transition.to (gp\_wheel2, { time = 500, rotation = -360, iterations=8} )
The body of the vehicle stays still in the Y axis as the group moves across the X.
Now here is the G2 version. Firstly, it requires 9 more lines of code to achieve the same thing. We have to set anchor is true, then work out where the object would be on the screen and add that. Working out where the group is takes calculations of the height, width, average x and y of the group’s contents and do math depending on where you want the anchor. Still more lines would be required if we suddenly needed to change the anchor mid way through to stop the groups contents from snapping to a new position. Anyway, here’s G2 version:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local gp\_carBody = display.newGroup() local gp\_wheel1 = display.newGroup() local gp\_wheel2 = display.newGroup() local gp\_car = display.newGroup() gp\_wheel1.anchorChildren = true gp\_wheel2.anchorChildren = true gp\_car.anchorChildren = true -- body positioning local body = display.newRect( 1472, 922, 748, 228 ) body:setFillColor( 255/255, 255/255, 255/255 ) -- top positioning local top = display.newRect( 1454, 758, 276, 260 ) top:setFillColor( 255/255, 255/255, 255/255 ) -- tyre1 positioning local tyre1 = display.newCircle( 1265, 1041, 75 ) tyre1:setFillColor( 3/255, 145/255, 222/255 ) -- cap1 positioning local cap1 = display.newCircle( 1265, 1041, 53 ) cap1:setFillColor( 255/255, 255/255, 255/255 ) -- tyre2 positioning local tyre2 = display.newCircle( 1689, 1041, 75 ) tyre2:setFillColor( 3/255, 145/255, 222/255 ) -- cap2 positioning local cap2 = display.newCircle( 1689, 1041, 53 ) cap2:setFillColor( 255/255, 255/255, 255/255 ) -- Organise Groups gp\_carBody:insert(body) gp\_carBody:insert(top) gp\_wheel1:insert(tyre1) gp\_wheel1:insert(cap1) gp\_wheel1.anchorX, gp\_wheel1.anchorY = 0.5, 0.5 gp\_wheel1.x, gp\_wheel1.y = 1265, 1041 gp\_wheel1.xScale = 0.5 gp\_wheel2:insert(tyre2) gp\_wheel2:insert(cap2) gp\_wheel2.anchorX, gp\_wheel2.anchorY = 0.5, 0.5 gp\_wheel2.x, gp\_wheel2.y = 1689, 1041 gp\_wheel2.xScale = 0.5 gp\_car:insert(gp\_carBody) gp\_car:insert(gp\_wheel1) gp\_car:insert(gp\_wheel2) gp\_car.anchorX, gp\_car.anchorY = 0.5, 0.5 gp\_car.x, gp\_car.y = 1472, 922 -- animation transition.to (gp\_car, { time = 4000, x = -200 } ) transition.to (gp\_wheel1, { time = 500, rotation = -360, iterations=8} ) transition.to (gp\_wheel2, { time = 500, rotation = -360, iterations=8} )
Now if you run this, the car is suddenly jiggling up and down in the y axis. The reason? Because the wheels are rotating, their height is changing which effects the overall height of the group gp_car which shifts up and down to remain anchored to the BottomCenter.
Now, if we were to anchor the gp_carBody which is nested in the gp_car then it’s crazy clown fun time. The car comes completely to bits… Try it by adding:
gp_carBody.anchorChildren = true
gp_carBody.anchorX, gp_carBody.anchorY = 0.5, 1
gp_carBody.x, gp_carBody.y = 1472, 1000
transition.to (gp_carBody, { time = 250, y = -50, iterations=16 } )
So you’re not wrong when you said that nested groups are no longer possible in Corona, or at least highly restricted in their application. This is a big shame because as an animator using Corona in G1 has been a joy and has led on to some great results. Things like walk cycles of characters rotating limbs and moving up and down while also moving across. Also squash and stretch where the anchor needs to change its position.
Having to add all this extra code to achieve only a small part of what you could do with reference points doesn’t seem like an evolution of the software especially since it actually no longer works no matter how much code you have to write…
I think you’ve found a bug.
Even if you comment out the xScale property of the wheels so they’re round, the car still bounces when the wheels are rotating.
If you also comment out the rotation transitions, the car remains stable.
Oh is that the case Ingemar? I didn’t try that. But you’re right, there must be something deeply wrong if it’s still jiggling around.
Also if you run G1 code in the latest public release simulator with v1 compatibility mode set then nested groups still have issues. So there must be something going on if it still manages to occur in this case…
What next, log this bug?
Your sample code is a good example of the problem.
If you leave the wheels round, I think it’s a good idea to log that bug.
I thought I had anchor points down, but as I’m playing around with your code I can’t wrap my head around some things I see.
There are weird things happening that I don’t understand. I’m also playing around with your sample adding containers instead of groups, but I’m struggling to get things the way I want them.
One thing that I totally agree on is that if V1 compatibility mode is activated, things should work exactly as they did in V1 without modifications, otherwise what’s the point?
I got it to work … without anchorChildren!
The anchorChildren property was causing all the problems. After removing that and adjusting the coordinates of the objects it looks OK and there are no more jitters while the wheels are turning.
I even implemented your bouncing “crazy clown fun time” feature… without the crazy clown :ph34r:.
Using anchorChildren can cause all sorts of unpredictable issues. This example has taught me that I might have to re-think my group positioning strategy as I’m also using anchorChildren=true in many places (however without any issues so far).
By rethinking the positioning in “G2.0 terms” it might just be possible to get everything working, however it *will* require an extensive re-write of the code to do so.
Remember that groups have no settable anchors. It uses the common anchor among the children.
You *can* use anchors among the children though to help with the internal positioning.
I guess that the final chapter in this story hasn’t been written yet, but here’s the code:
-- -- main.lua -- display.setStatusBar(display.HiddenStatusBar) local gp\_carBody = display.newGroup() local gp\_wheel1 = display.newGroup() local gp\_wheel2 = display.newGroup() local gp\_car = display.newGroup() -- body positioning local body = display.newRect(0, 0, 748, 228 ) body.anchorY = 0; body:setFillColor(0.9) -- top positioning local top = display.newRect(0, 0, 276, 260 ) top.anchorY = 1; top:setFillColor(1) -- tyre1 positioning local tyre1 = display.newCircle(0, 0, 75 ) tyre1:setFillColor( 3/255, 145/255, 222/255 ) -- cap1 positioning local cap1 = display.newCircle(0, 0,53 ) cap1:setFillColor( 255/255, 255/255, 255/255 ) -- tyre2 positioning local tyre2 = display.newCircle(0, 0, 75) tyre2:setFillColor( 3/255, 145/255, 222/255 ) -- cap2 positioning local cap2 = display.newCircle(0, 0, 53 ) cap2:setFillColor( 255/255, 255/255, 255/255 ) -- Organise Groups gp\_carBody:insert(body) gp\_carBody:insert(top) gp\_wheel1:insert(tyre1) gp\_wheel1:insert(cap1) gp\_wheel1.x, gp\_wheel1.y = gp\_carBody.x - 200, gp\_carBody.height / 2 gp\_wheel1.xScale = 0.5 gp\_wheel2:insert(tyre2) gp\_wheel2:insert(cap2) gp\_wheel2.x, gp\_wheel2.y = gp\_carBody.x + 200, gp\_carBody.height / 2 gp\_wheel2.yScale = 0.5 gp\_car:insert(gp\_carBody) gp\_car:insert(gp\_wheel1) gp\_car:insert(gp\_wheel2) gp\_car.x, gp\_car.y = 1000, 600 -- animation transition.to (gp\_carBody, {time=250, y=-25, iterations=16, transition=easing.continuousLoop} ); transition.to (gp\_car, { time = 4000, x = -200} ) transition.to (gp\_wheel1, { time = 500, rotation = -360, iterations=8} ) transition.to (gp\_wheel2, { time = 500, rotation = -360, iterations=8} )
Nice work Ingemar, you’ve found a work around so at least nesting is possible … albeit involving a great deal more calculation…
But yes, good idea to actually not use anchor = true as it is unpredictable, not a great word when it comes to coding. The way we work, it isn’t intuitive to set layers at 0,0 as a number of things need to be laid out in relation to each other. I guess what’s needed is to set graphic layers out as usual, then pass them through a function if another anchor is required other than 0.5, 0.5 which sets obj.y, obj.x to 0,0, sets a passed in anchor then returns an adjusted x and y according to the new anchor and the original x and y… Hmmm could be doable. Doing the same for groups is difficult. Maybe calculate where a group is according to where the average of the group’s children are in x and y? Again a bit of code here required to get back what we lost in G1 Glad to have identified the corrupt nature of anchorChildren at the beginning of a big project rather than half way through. As for the already completed apps with heavy group nesting… that’s another painful story. Nice work Ingemar.
Have started a new thread to focus on the evolution of this code to make nested groups work again:
http://forums.coronalabs.com/topic/46954-solution-to-fix-nested-groups-in-g20/