This is probably an incredibly simple answer, but I have no idea why the following code is behaving as it is:
auto par = Sprite::create("res/cross.png");
par->setPosition(500, 500);
addChild(par);
auto child = Sprite::create("res/cross.png");
child->setPosition(300, 0);
par->addChild(child);
I set a parent sprite to the position 500, 500. That works. Great. I create a child and set its position relative to the parent so that it should be 300px to the right of the parent. I then add the child to the parent. Both display, and yet the child is shifted downward from the parent (in addition to being shifted right)! My expectation is that since I set the child to be at position (300,0) it should be 300px to the right of the parent (and not shifted up or down whatsoever). Itâs like the child is taking the bottom-left of the parent as the relative coordinate rather than the parentâs anchor point.
Why is that? Shouldnât setPosition set the relative position from the parentâs effective anchor position to the childâs effective anchor position? I have no idea why this is blowing my mind, but it sure is.
Hereâs an example of the output, where the parent is the leftmost cross:
Itâs funny â this is reproducible in seconds using Cocos Studio 2. Itâs just so counter-intuitive to me that I thought I must be doing something wrong or have somehow exposed a weird bug.
So if my understanding is correct it looks like positioning of children is based not on the anchor point of the parent but on the bottom left? Is that correct? Does that seem crazy to anybody else?!
Parent has anchor point at (0.5,0.5)
Child has same anchor point, and a position of (100,0)
So the child is vertically central and 100px to the right of centre.
Set the parentâs anchor point to (0,0.5)
The parent will now âmoveâ width/2 pixels to the right - but its child will stay still (according to the viewer0 - which is counter intuitive (well, I think so!)
I think of the position of the sprite as being where it actually is - whereas the anchor point determines the offset of the graphical representation of the sprite.
I like your thought experiment about the shifting anchor point and how the parent would move without the child. Itâs a good counter-point. I need to start thinking of the sprites exactly as you mentioned: "the anchor point determines the offset of the graphical representation. That should help me overcome what I see as the counter-intuitive behaviour. Thanks so much for chiming in!
Thanks for the suggestion Mikhail â my problem wasnât so much how to get the object aligned as that in the small example I provided I thought the outcome was very surprising. I knew I could fix the issue by shifting numbers around, I just wanted to get an understanding of what the logic was behind this arrangement. Thanks for the great pictures, though! They help to clarify the issue!
I remember (vaguely - 'twas a long time ago!) being confused similarly - so much so that my first few experiments set the anchor point to (0,0) - which actually means in many cases the maths is easer too (no more dividing by two!)
I did read that article when I was wallowing in confusion over this. Can you please point out which part of that article you believe clearly answers this question? I actually think it confused me more. Specifically, lines like this:
âAnchor Point is a point that you set as a way to specify what part of the Sprite will be used when setting its position.â
imply that the position of a sprite is always based on its anchor point. Which would make me think it was dependent upon its parentâs anchor point. Which itâs not!
Gosh, the way anchor point works really sucks. The only way to make it âworkâ is to not use it at all =(0,0) and just replace it with another node in the hierarchy which will play the role of the anchor point.
Not at all well-documented way things work. In fact, itâs so confusing that itâs a bad idea having anchor set to (0.5,0.5) by default!
I think the really confusing part for me was that I expected a childâs anchor point to respect the parentâs anchor point.
For example, if youâve used Unity, the parent/child relationship works that way. The childâs position is relative to the parentâs âanchorâ position (transform). So when I was trying to place objects in Cocos (after coming from Unity), I would always be trying to place them with respect to their parentâs anchor point, when I believe the correct approach in Cocos is to place them based on the bottom left of the parent sprite, regardless of the position of the anchor point in the parent. I kept getting caught by that because it violated my expectations coming from Unity. I wouldnât say that Cocos is doing it âwrongâ, but personally I donât find the design nearly as intuitive as I think it could be.
Well, maybe Flash (AS3) doesnât allow you to have children to Sprites (âBitmapsâ in AS3) exactly to avoid this kind of confusion. Children are only allowed on Nodes (âSpritesâ in AS3).
I disagree - once you get your head around it is is logical and simple.
Imagine your sprite is a picture youâre hanging on a wall panel. You want to put it 2m from the left and 1m high - so bang a nail at (2,1) in the panel, and hang the picture on it.
If you put the nail through the middle of the picture (anchor point (0.5,0.5) - half way across and half way up the picture) then I think thatâs easy to understand.
If you want to move the picture slightly, you can adjust where the nail goes through the picture - rather than moving the nail.
Now, imaging âzooming outâ and seeing that the panel is actually just a small panel attached to a large wall.
The panel might have had its âanchor pointâ anywhere! bottom left, just offset from the centre - who knows? And thatâs the point! If the pictureâs position depended on the panelâs anchor point, you would have to have referenced that anchor point to position your picture correctly - and if the wall was actually a panel on a larger wallâŚ
The best way to get your head round it is to write some code. Create a program that displays a small square sprite as a child of a larger one that is itself the child of a larger one.
Start off with all the anchor points as (0.5,0.5) and position each at the midpoint of its parent. then adjust the anchorpoints smoothly between 0 and 1 - it all makes sense when you see it in action like that (well, it did for me)
Unfortunately I canât find the program I knocked up to do this, or Iâd post it somewhere.