I am trying to create a simple helper method to detect whether a UITouch is within a CCSprite's bounds with this method:
- (BOOL)containsTouchLocation:(UITouch *)touch {
CGPoint p = [self convertToNodeSpace:touch.locationInWorld];
CGRect r = self.boundingBox;
return CGRectContainsPoint(r, p);
}
It seems like it should work in retrospect but it just returns "NO" even though the touch is clearly in a sprite on the screen. Is there something I am doing wrong here? I am using Cocos2d v3.
What you are doing wrong is that boundingBox
is the analog of frame
and not bounds
. Therefore r
is in coordinate space of the parent
of the node and p
in coordinate space of the node itself.
If you know that node has a parent you can calculate p
in parents coordinate space:
CGPoint p = [self.parent convertToNodeSpace:touch.locationInWorld];
// You can also use a shorthand [touch locationInNode: self.parent];
Or instead you could get r
as the bounds
rect instead of the frame
// notice that it is `contentSizeInPoints` and not `contentSize`
CGRect r = { .origin = CGPointZero, .size = self.contentSizeInPoints };
But either way the CCNode
now also has hitAreaExpansion
which you might want to take into account:
r = CGRectInset(r, -self.hitAreaExpansion);
Or instead of doing all this you could use the hitTestWithWorldPos:
method, default implementation of which tests whether given world location is within bounds of the node +/- hitAreaExpansion
.