Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I display the bounding box for a CCNode in cocos2d?

As a follow-on question to my previous question about displaying the anchor point, I subclassed CCSprite and changed its draw method as follows:

[super draw];
ccDrawColor4F(0, 1, 0, 1);
ccDrawCircle(self.anchorPointInPoints, 20, 0, 8, YES);

This works great. For extra credit, I added the following to display its bounding box:

CGRect bb = self.boundingBox;
CGPoint vertices[4] = {
    [self convertToNodeSpace:ccp(bb.origin.x, bb.origin.y)],
    [self convertToNodeSpace:ccp(bb.origin.x + bb.size.width, bb.origin.y)],
    [self convertToNodeSpace:ccp(bb.origin.x + bb.size.width, bb.origin.y + bb.size.height)],
    [self convertToNodeSpace:ccp(bb.origin.x, bb.origin.y + bb.size.height)],
};
ccDrawPoly(vertices, 4, YES);

This also works great, until I reparent a sprite:

CGPoint oldPosition = [sprite convertToWorldSpace:sprite.position];
[sprite removeFromParentAndCleanup:NO];
[parentSprite addChild:sprite];
sprite.position = [sprite convertToNodeSpace:oldPosition];

The sprite's now in the proper position and its anchor point draws where it should, but the bounding box draws in the wrong place. What am I doing wrong?

like image 334
Dylan Avatar asked Aug 27 '12 00:08

Dylan


2 Answers

I normally draw AABBs with:

Rect aabb = someNode->getBoundingBox();
DrawNode* drawNode = DrawNode::create();
drawNode->drawRect(aabb.origin, aabb.origin + aabb.size, Color4F(1, 0, 0, 1));
parentNode->addChild(drawNode, 100);

Note: If the Rect aabb size is (0,0) then the rectangle will not be drawn.

like image 159
nikc Avatar answered Nov 22 '22 10:11

nikc


Bounding box of a node is relative to its parent. Drawing done in draw method is in node's local space. convertToNodeSpace: converts coordinates from world space to local space, not from parent's space.

When you reparent node to a parent with different origin while maintaining same "world" position of this node, origin of its bounding box changes.

Your mistake is that you treat your sprite's bounding box as if its coordinates were in world space.

Second, you don't need to do the convert-to-x-space dance to draw bounding box of a sprite. Open ccConfig.h file in cocos2d folder of your project and change

#define CC_SPRITE_DEBUG_DRAW 0

line to

#define CC_SPRITE_DEBUG_DRAW 1

Third, coordinates of sprite.position point are relative to its parent, not to the sprite. When you call [node convertToWorldSpace:aPoint], it will treat aPoint as if it were in node's local space. If you want to get world coordinates of a node's position, you should call convertToWorldSpace: on node's parent: [node.parent convertToWorldSpace:node.position].

like image 21
Kreiri Avatar answered Nov 22 '22 10:11

Kreiri