触摸检测问题

时间:2012-01-15 20:36:54

标签: ipad cocos2d-iphone touch

我只是在学习Cocos2d和Objective-C,我在触摸检测方面遇到了一些问题。

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

然后我有一些代码可以动摇一个被触动的精灵:

- (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),但我不知道如何。

我在论坛上度过了几个晚上,但我仍然无法理解如何让顶级精灵摇晃......

1 个答案:

答案 0 :(得分:0)

尝试更类似的内容(请注意ccTouchesBegan而不是ccTouchBegan):

- (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];
        }
    }
}

selectSpriteForTouch中设置for循环的方式将导致只选择draggableSprites中的第一个对象,因为您的break语句。使用这个新代码,其边界框包含触摸的每个精灵都将被动画化。代码可能不完美,因为我直接输入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中删除。然后,我们自动发布它,以便我们没有内存泄漏。