1
votes

I'm writing a cocos2d-x application. I have a sprite with a couple of child sprites over it. These sprites represent one logical object on the screen that is transformed as a whole object. Now, when the object is touched, I need to discover which of the child sprites was touched.

The problem is that, while the parent sprite gives me all the information (bounding box, scale, rotation etc.) as it currently is, the child sprites stay with their original numbers, despite being transformed together with the parent, and I cannot figure out the correct way to calculate the "real" dimensions for the children.

As it looks to me, two facts cause all the difficulties:

  1. The child bounding box has its initial dimensions which are reported relative to the parent's initial bounding box.
  2. I cannot calculate the parent's initial bounding box after the parent was rotated (see the picture below), thus I cannot calculate where now is the lower left corner of the parent sprite, which I need as the relation point for child transformations.

Here's a drawing of such a situation:

Sprite bounding box after rotation

So, to summarize, in order to check whether a touch hit a child sprite, I need to calculate the current bounding box of the children, based on the parent's transformations. I can calculate the scaling and the rotation of the child, but I don't know where it should be positioned relative to the parent because the parent's bounding box is very different from what it was in the beginning. Add weird anchor points to the story and it becomes even more complicated. The perfect solution would be to get the vertices of the original sprite and not the bounding box. Is it possible?

Any ideas? Am I missing something?

3

3 Answers

1
votes

The source code of boundingBox() maybe helpful. You can get the affinetransform by nodeToParentTransform(),and use CCPointApplyAffineTransform to get the new position of the four points. Then you can write a new method to check if the touch locate in the new rect.

0
votes

Assume you Have a parent

CCSprite* parent;

and a Child,

CCSprite* child; //child Tag is 100

you can give it a try in your touch method:

YOUR_CLASS::ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent){
    CCPoint touchLocation = parent->convertTouchToNodeSpace(pTouch);
    if (CCRect::CCRectContainsPoint(parent->getChildByTag(100)->boundingBox(),touchLocation)){
        //do something
        CCLOG("touch on child");
    }
}
0
votes

If someone wants to find out the letters bounding boxes in a rotated label:

int maxIdx = label->getStringLength() -1;
Mat4 trans = label->getNodeToParentTransform();
for(int idx = 0; idx<=maxIdx; idx++) {
    Sprite* letter = label->getLetter(idx);
    Rect letterRect = letter->getBoundingBox();
    Point p = PointApplyTransform(letterRect.origin, trans);
    Rect rect = Rect(p.x, p.y, 10, 10); // Letter Approximation rect
}