2010-07-18 72 views
4

如何檢測旋轉的CCSprite上的觸摸?Cocos2d:檢測旋轉精靈上的觸摸?

我熟悉使用ccTouchesBegan和contentSize,anchorPoint等的一般技術,讓sprite檢測觸摸是否在其邊界內......但我不確定一旦sprite被旋轉一些角度。

我想讓精靈本身檢測觸摸(封裝)並通過委託將事件報告給另一個對象。

如果有人有一些代碼分享...會很好。

回答

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 
+0

謝謝!工作就像一個魅力... – poundev23 2010-07-23 00:40:51

+0

無論如何要做到這一點在cocos2d 2?我收到一些錯誤。我認爲有些東西因爲寫了這些東西而被棄用。謝謝! – Corey 2013-03-18 21:53:50

+0

適合我。這應該被構建到cocos2d中。 :-) – 2013-04-13 23:07:43

5

@爸爸的代碼轉換節點的BBOX到世界各地。對於旋轉的節點,這擴展了bbox,並且可以在實際節點之外但在世界bbox內的觸摸返回true。爲了避免這種情況,將世界點轉換爲節點的座標空間,並測試其中的本地點。

+1

我相信我遇到了你在這裏描述的問題,但我不理解你提出的解決方案。你能詳細說明嗎? – mwright 2012-03-28 16:14:35

+0

好點,好建議 – Dad 2013-06-03 18:17:53

2

由於苦艾酒說 - 的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); 

有一個很好的代碼!

編輯: 好的解決方案!我將它轉換爲Objective 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; 
} 
+1

轉換爲Obj-C並添加爲編輯。非常感謝。 – jarryd 2013-07-01 16:06:39