如何检测旋转的CCSprite上的触摸?
我熟悉使用ccTouchesBegan和contentSize,anchorPoint等的一般技术,如果触摸在其范围内,可以检测精灵......但是我不知道一旦精灵旋转后如何继续角。
我希望sprite本身能够检测到触摸(封装)并通过委托将事件报告给另一个对象。
如果有人要分享一些代码......会很棒。
答案 0 :(得分:6)
尝试使用CCNode convertTouchToNodeSpaceAR:方法将点转换为旋转坐标,然后您可以比较精灵边界。
我在CCNode上将其设为一个类别,因此可供任何CCNode或子类使用。
@interface CCNode (gndUtils)
// Lets a node test to see if a touch is in it.
// Takes into account the scaling/rotation/transforms of all
// the parents in the parent chain.
// Note that rotation of a rectangle doesn't produce a rectangle
// (and we are using a simple rectangle test)
// so this is testing the smallest rectangle that encloses the rotated node.
// This does the converstion to view and then world coordinates
// so if you are testing lots of nodes, do that converstion manually
//
// CGPoint touchLoc = [touch locationInView: [touch view]]; // convert to "View"
// touchLoc = [[CCDirector sharedDirector] convertToGL: touchLoc]; // move to "World"
// and then use worldPointInNode: method instead for efficiency.
- (BOOL) touchInNode: (UITouch *) touch;
// allows a node to test if a world point is in it.
- (BOOL) worldPointInNode: (CGPoint) worldPoint;
@end
和实施:
@implementation CCNode (gndUtils)
- (BOOL) touchInNode: (UITouch *) touch
{
CGPoint touchLoc = [touch locationInView: [touch view]]; // convert to "View coordinates" from "window" presumably
touchLoc = [[CCDirector sharedDirector] convertToGL: touchLoc]; // move to "cocos2d World coordinates"
return [self worldPointInNode: touchLoc];
}
- (BOOL) worldPointInNode: (CGPoint) worldPoint
{
// scale the bounding rect of the node to world coordinates so we can see if the worldPoint is in the node.
CGRect bbox = CGRectMake( 0.0f, 0.0f, self.contentSize.width, self.contentSize.height ); // get bounding box in local
bbox = CGRectApplyAffineTransform(bbox, [self nodeToWorldTransform] ); // convert box to world coordinates, scaling etc.
return CGRectContainsPoint( bbox, worldPoint );
}
@end
答案 1 :(得分:5)
@Dad的代码将节点的bbox转换为世界。对于旋转节点,这会扩展bbox,并且对于实际节点之外但在世界bbox内部的触摸,可以返回true。要避免这种情况,请将世界点转换为节点的坐标空间,并在那里测试本地点。
答案 2 :(得分:2)
正如 Absinthe 所说 - poundev23 的代码实际上只检查旋转的精灵周围的BB。 我写了正确的代码(但在Cocos2dx - c ++上) - 希望它对某人有所帮助:
CCSize size = this->getContentSize();
CCRect rect = CCRect(0, 0, size.width, size.height);
CCPoint pt = touch->locationInView();
pt = CCDirector::sharedDirector()->convertToGL(pt);
pt = CCPointApplyAffineTransform(pt, this->worldToNodeTransform());
bool b = CCRect::CCRectContainsPoint(rect, pt);
有一个很好的代码!
编辑: 好的解决方案我把它转换成了目标C.
- (BOOL) containsTouchLocation:(UITouch *) touch
{
CGSize size = self.contentSize;
CGRect rect = CGRectMake(0, 0, size.width, size.height);
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
touchLocation = CGPointApplyAffineTransform(touchLocation, self.worldToNodeTransform);
bool containsPoint = CGRectContainsPoint(rect, touchLocation);
return containsPoint;
}