What am I not understanding about anchor points and positioning?!

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:

1 Like

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?!

Say it was related to the anchor point.

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.

1 Like

I have tried to illustrate it:

So if you want your child sprite to be to the right of parent sprite set y anchor point to zero for child:
childSprite->setAnchorPoint(Point(0,0));

2 Likes

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!)

http://cocos2d-x.org/docs/programmers-guide/3/index.html#sprite-manipulation

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!

1 Like

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! :disappointed_relieved:

I’m not sure I agree. anchor point is a solid concept.

You can read here, a bit down: http://cocos2d-x.org/docs/programmers-guide/basic_concepts/index.html

and: http://cocos2d-x.org/docs/programmers-guide/sprites/index.html#sprite-manipulation

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.

this is correct.

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 think I will follow their approach here, too.

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.