# Cocos2d-x Finding if a CCPoint is inside a sprite rect

I'm afraid that I'm missing something. This is what I've done:

1. I've made a scene using layers (Gimp), then I've exported the layers with the image size, that way I thought would be more easy to add the images and have the offsets in the right way.
2. I made a spritesheet with TexturePacker, trimming the images.

Then I have in the plist file something like:

<dict>
<key>frame</key>
<string>{{1028,360},{326,382}}</string>
<key>offset</key>
<string>{-316,110}</string>
<key>rotated</key>
<false/>
<key>sourceColorRect</key>
<string>{{33,83},{326,382}}</string>
<key>sourceSize</key>
<string>{1024,768}</string>
</dict>


Then in my code I've made a CCSprite:

granero = CCSprite::createWithSpriteFrameName("04_Granero.png");


And the ccTouchBegan:

bool Escena00::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
// This point has the touch location info
CCPoint touchPoint = CCPoint(touch->getLocationInView().x, touch->getLocationInView().y);

// Now I want to set a rect, where a little house in the screen is located
CCRect *graneroRect = new CCRect(granero->getOffsetPosition().x, granero->getOffsetPosition().y,granero->getTextureRect().size.width,granero->getTextureRect().size.height);

if (graneroRect->containsPoint(touchPoint))
{
CCLog("The little house in the left was touched");
}

return true;
}


If you take a look now to the plist extract that I've posted you'll read the "sourceColorRect" key. Those coords are the right numbers that I need to use to create my CCRect (33,83, 326, 382). With those numbers I've been able to correctly get the touch over the little house. However, I don't want to use those numbers with a "hard way". Using granero->getOffsetPositionX(), I get the "33" number, and using the "getTextureRect()" I can get the third and fourth numbers (size of the rect). The big issue is the getOffsetPositionY(), or any "y" coordinate. I can't read the "83" number. How can I solve this? Or what am I doing wrong?

I'll answer my question, but @akg is the answer that guided me. I've made the code in cocos2d-x, and I didn't used boundingBox() method. Hope this helps someone, :) I didn't found something like this in other site, so I hope not be doing something wrong...

bool SceneGame::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CCPoint touchPoint = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());

touchPoint = littleHouse->convertToNodeSpace(touchPoint);

CCRect *littleHouseRect= new CCRect(littleHouse->getOffsetPosition().x
,littleHouse->getOffsetPosition().y
,littleHouse->getTextureRect().size.width
,littleHouse->getTextureRect().size.height);

if (littleHouseRect->containsPoint(touchPoint))
{
CCLog("The little house in the left was touched");
}

return true;
}

• This works even without the "touchPoint = littleHouse->converToNodeSpace(touchPoint);" lines – Jose M Pan Aug 17 '13 at 4:07
• Thank you Jose. But it would be easier to just use Point touchPoint = littleHouse->convertTouchToNodeSpace(touch);. – Narek Jun 23 '14 at 15:03

I think you need to make sure that you have the correct coordinate system. The best way is to use Cocos2d builtins to convert to the desired coordinate system and then check if the touch is within your desired bounding box:

- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchStart = [[CCDirector sharedDirector] convertToGL:[touch locationInView:[touch view]]];

// Convert touch into the appropriate coordinate space of the sprite.
touchStart = [yourSprite convertToNodeSpace:touchStart];

// Handle block stash touch.
CGRect boundingBox = [yourSprite boundingBox];
if (CGRectContainsPoint(boundingBox, touchStart)) {
// process touch...
}
}

• Your answer is almost correct, :), I've just finished with the "translation" to cocos2d-x. The only problem is the boundingBox(). With boundingBox I get all the screen as the "little house". I've solved using the same rect that I've posted initially: CCRect *graneroRect. – Jose M Pan Jul 31 '13 at 23:12

try this code:


bool Escena00::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if (isNodeAtPoint(granero, touch->getLocation()) {
CCLog("The little house in the left was touched");
}

return true;
}

bool Escena00::isNodeAtPoint(cocos2d::CCNode* node, cocos2d::CCPoint& touchLocation) {
CCPoint nodePoint = node->convertToNodeSpace(touchLocation);
CCRect rect = CCRectMake(0, 0, node->getContentSize().width, node->getContentSize().height);
return rect.containsPoint(nodePoint);
}

• With this code everytime I touch the screen I get "The little...". Instead, I've tried changing CCNode for CCSprite, and getContentSize for getTextureRect().size.width. Now looks like it takes the correct Rect, but now that rect is in the lower left corner. I know this is because a spritesheet has its 0,0 at upper left, and cocos work with 0,0 at lower left. But why if I use Rect(33,83,326,382) I do get the correct "activation rectangle"? – Jose M Pan Jul 31 '13 at 21:59
• To clarify a little more: I have a house in a 1024x768 image, located at 33,83 (x,y) with size 326,382 (w,h). I packed that with TexturePacker, now I want to check if the touch location is in that rect (33,83,326,382)... But I have a coordinate mess – Jose M Pan Jul 31 '13 at 22:17

If you wish to detect if a ccpoint in inside a sprite rectangle in Cocos2D-HTML5, checkout this quick snippet:

onTouchesEnded:function (touches, event) {

for( n=0; n < touches.length; n++) {

var touch = touches[n];

if (cc.rectContainsPoint(this.yoursprite.getBoundingBox(), touch.getLocation()) == true) {
// Sprite has been touched
}
}
}

• Link-only answers aren't really what we're looking for (since links often go out of date). The solution should actually be presented in your answer, not just linked. – Trevor Powell May 25 '14 at 9:16