2012-01-15 101 views
0

我刚刚学习Cocos2d和Objective-C,并且在触摸检测方面存在一些问题。触摸检测问题

我在HelloWorldLayer和一些draggableSprites(NSMutableArray)有几个精灵。其中两个可拖放的精灵位于另一个之上(最下面的一个更大)。

然后,我有一些代码,震动触摸精灵:

- (void)selectSpriteForTouch:(CGPoint)touchLocation { 
    CCSprite *touchSprite = nil; 
    for (CCSprite *sprite in dragableSprites) { 
     if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {    
      touchSprite = sprite; 
      break; 
     } 
    }  
    if (touchSprite != selSprite) { 
     [selSprite stopAllActions]; 
     [selSprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]]; 
     CCRotateTo * rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-1.0]; 
     CCRotateTo * rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0]; 
     CCRotateTo * rotRight = [CCRotateBy actionWithDuration:0.1 angle:1.0]; 
     CCSequence * rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil]; 
     [touchSprite runAction:[CCRepeatForever actionWithAction:rotSeq]];    
     selSprite = touchSprite; 
    } 
} 

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { 
    CGPoint touchLocation = [self convertTouchToNodeSpace:touch]; 
    [self selectSpriteForTouch:touchLocation]; 
    return TRUE; 
} 

但是当我接触的顶部或底部的精灵,只有底部有一个惊天(这是第一次加入INIT)。

我认为我需要替换代码CGRectContainsPoint(sprite.boundingBox, touchLocation),但我只是不知道如何。

我花了几个晚上的论坛,但我仍然无法理解如何让顶级精灵抖动......

回答

0

尝试更多的东西像这样(注意它是不是ccTouchesBeganccTouchBegan):

- (void)startShakingSprite:(CCSprite*)sprite { 

    [sprite stopAllActions]; 
    [sprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]]; 
    CCRotateTo* rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-1.0]; 
    CCRotateTo* rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0]; 
    CCRotateTo* rotRight = [CCRotateBy actionWithDuration:0.1 angle:1.0]; 
    CCSequence* rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil]; 
    [sprite runAction:[CCRepeatForever actionWithAction:rotSeq]]; 
} 

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent*)event { 
    //get the touch 
    UITouch* touch = [touches anyObject]; 
    //get its location 
    CGPoint location = [touch locationInView:[touch view]]; 
    //convert location to cocos2d coordinates 
    CGPoint point = CGPointMake(location.x, 480 - location.y); 

    //now we go through your array of objects and see which contains the touch 
    for(id sprite in draggableSprites) { 
     if(CGRectContainsPoint(sprite.boundingBox, point)) { 
      [self startShakingSprite:sprite]; 
     } 
    } 
} 

由于break语句的原因,在selectSpriteForTouch中设置for循环的方式仅会导致draggableSprites中的第一个对象被选中。使用这个新代码,每个sprite的边界框包含touch将被动画化。代码可能并不完美,因为我直接输入到Chrome中,但您明白了。

需要注意的另一个重要的事情是,你不能在两个不同的精灵运行同样的动作,这样的:

id action = [CCScaleTo actionWithDuration:1 scale:1.0]; 
[someSprite runAction:action]; 
[someOtherSprite runAction:action]; 
[oneMoreSprite runAction:action]; 

此代码将不会按预期进行;只有最后一个精灵(oneMoreSprite)会动画。为了重新使用多精灵CC动画,使用此代码:

id action = [CCScaleTo actionWithDuration:1 scale:1.0]; 
[someSprite runAction:action]; 
[someOtherSprite runAction:[[action copy] autorelease]]; 
[oneMoreSprite runAction:[[action copy] autorelease]]; 

我们做动作的副本,以便它可以由另一个精灵(someOtherSpriteoneMoreSprite)来运行,而不会从原来的精灵移除,someSprite。然后,我们autorelease它,所以我们没有内存泄漏。

+0

谢谢!删除Break语句有助于顶级精灵。 – OnOff 2012-01-15 21:10:20

+0

很高兴能帮到你! – 2012-01-15 21:13:15