0

我是 cocos2d 的初学者,我面临着检测硬币碰撞的问题。有时它起作用,有时它不起作用。

所以基本上,我正在创建一个游戏,用户(船)必须避开障碍物并在途中收集硬币。障碍物的碰撞效果很好,但对于硬币来说却不行。我在想也许创建许多硬币的循环是问题,但我不确定。

任何人都可以帮忙吗?

我的代码:

- (void)update:(ccTime)dt{
double curTime = CACurrentMediaTime();
if (curTime > _nextBridgeSpawn) {

    float randSecs = [self randomValueBetween:3.0 andValue:5.0];
    _nextBridgeSpawn = randSecs + curTime;

    float randX = [self randomValueBetween:50 andValue:500];
    float randDuration = [self randomValueBetween:8.0 andValue:10.0];

    CCSprite *bridge = [_bridge objectAtIndex:_nextBridge];

    _nextBridge++;

    if (_nextBridge >= _bridge.count) _nextBridge = 0;

    [bridge stopAllActions];
    bridge.position = ccp(winSize.width/2, winSize.height);
    bridge.visible = YES;

    [bridge runAction:[CCSequence actions:
                         [CCMoveBy actionWithDuration:randDuration position:ccp(0, -winSize.height)],
                         [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
                         nil]];

这是我声明我的硬币的地方(续更新方法)

    int randCoin = [self randomValueBetween:0 andValue:5];
    _coin = [[CCArray alloc] initWithCapacity:randCoin];
    for(int i = 0; i < randCoin; ++i) {
        coin = [CCSprite spriteWithFile:@"coin.png"];
        coin.visible = NO;
        [self addChild:coin];
        [_coin addObject:coin];
    }

    float randCoinX = [self randomValueBetween:winSize.width/5 andValue:winSize.width - (border.contentSize.width *2)];
    float randCoinY = [self randomValueBetween:100 andValue:700];
    float randCoinPlace = [self randomValueBetween:30 andValue:60];
    for (int i = 0; i < _coin.count; ++i) {
        CCSprite *coin2 = [_coin objectAtIndex:i];
        coin2.position = ccp(randCoinX, (bridge.position.y + randCoinY) + (randCoinPlace *i));
        coin2.visible = YES;
        [coin2 runAction:[CCSequence actions:
                          [CCMoveBy actionWithDuration:randDuration position:ccp(0, -winSize.height-2000)],
                          [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
                          nil]];  
    }

}

这是为了检查碰撞(也在更新方法中)

for (CCSprite *bridge in _bridge) {        
    if (!bridge.visible) continue;

if (CGRectIntersectsRect(ship.boundingBox, bridge.boundingBox)){
            bridge.visible = NO;
            [ship runAction:[CCBlink actionWithDuration:1.0 blinks:5]];         

        }
    }
}

//this is the collision for coins which only work at times
    for (CCSprite *coin2 in _coin) { 

        if (!coin2.visible) continue;

        if (CGRectIntersectsRect(ship.boundingBox, coin2.boundingBox)) {
            NSLog(@"Coin collected");
            coin2.visible = NO;
        }

    }

}

谢谢你。

4

3 回答 3

0

为什么你不检查距离?

 float dist = ccpDistance(ship.position, coin2.position); 
 float allowedDist = ship.contentSize.width*0.5 + coin2.contentSize.width*0.5;
 if (dist<allowedDist){
   NSLog(@"Collision detected");
 }

如果您的精灵不在同一层上,则这些层应至少具有相同的位置。

于 2012-05-31T07:36:54.763 回答
0

最后一段代码中的电话是什么?你在那里检查它的boundingBox是否与硬币相交,但我在其他任何地方都看不到它。另一个,boundingBox 仅当您的对象具有相同的父对象时才有效,因为它返回“本地”矩形,相对于它的父对象

另一点是,如果您的对象的移动速度过快,它们可能会在滴答时间内互相通过。我的意思是,一个更新将在碰撞之前被调用,所以它不会检测到它,下一个将在碰撞完成后调用,所以它也不会检测到它。

于 2012-05-31T07:02:00.707 回答
0

我通过在 init 中创建一个计时器并每 10 秒调用一次来创建我的硬币来解决我的问题。

我的代码:

-(void) createCoins:(ccTime)delta{ 

CGSize winSize = [CCDirector sharedDirector].winSize;

int randCoin = [self randomValueBetween:0 andValue:10];
_coin = [[CCArray alloc] initWithCapacity:randCoin];
for(int i = 0; i < randCoin; i++) {
    coin = [CCSprite spriteWithFile:@"coin30p.png"];
    coin.visible = NO;
    [self addChild:coin];
    [_coin addObject:coin];
}
float randCoinX = [self randomValueBetween:winSize.width/5 andValue:winSize.width - (border.contentSize.width *2)];
float randCoinY = [self randomValueBetween:100 andValue:700];
float randCoinPlace = [self randomValueBetween:30 andValue:60];
for (int i = 0; i < _coin.count; i++) {
    CCSprite *coin2 = [_coin objectAtIndex:i];
    coin2.position = ccp(randCoinX, (winSize.height + randCoinY) + (randCoinPlace *i));
    coin2.visible = YES;

    [coin2 runAction:[CCSequence actions:
                      [CCMoveBy actionWithDuration:8 position:ccp(0, -winSize.height-2000)],
                      [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
                      nil]];  
}

}

在更新方法中:

for (CCSprite *coins in _coin){
    if (!coins.visible) continue;
    if (CGRectIntersectsRect(phone.boundingBox, coins.boundingBox)) {
        NSLog(@"Coin collected");
        coins.visible = NO;
    }

}

谢谢大家的帮助(:

于 2012-05-31T08:08:31.590 回答