Проблема завершения игры Cocos2d, когда движущийся спрайт входит в ограничивающую рамку анимирующего неподвижного спрайта (мяч попадает в отверстие) - PullRequest
0 голосов
/ 27 августа 2011

Позвольте мне объяснить это подробно, когда когда-либо if(CGRectContainsPoint([hole1 boundingBox], ball1.position)) условие сбывается, я делаю много вещей, таких как незапланированный, селектор, уничтожая тело шара, вызывая анимацию ( пожалуйста, обратитесь к коду ниже )и т.п.Это работает правильно большую часть времени.Но иногда, когда мяч действительно находится рядом с лункой (просто касается лунки, но не достаточно, чтобы выполнить указанное выше условие), или когда его бросают к лунке на очень быстрой скорости, приложение прекращается.Я проверил, комментируя многие действия, которые были выполнены в этом разделе, но не получил ничего полезного, приложение продолжает завершать работу, когда предпринимаются некоторые усилия для его завершения.

if(CGRectContainsPoint([hole1 boundingBox], ball1.position))
{
    ballBody->SetLinearVelocity(b2Vec2(0.0f,0.0f));
    ballBody->SetAngularVelocity(0.0f);

    [self unschedule:@selector(tick:)];
    self.isTouchEnabled = NO;

    [self removeChild:ball1 cleanup:YES];
    world->DestroyBody(ballBody);

    // create the sprite sheet
    CCSpriteSheet *spriteSheet;

    GolfBallsAppDelegate *appDelegate = (GolfBallsAppDelegate *)[[UIApplication sharedApplication] delegate];
    if([appDelegate.ballValue isEqualToString:@"cricketball"])
    {
        spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"cricket_ball_strip.png"];
    }
    else if([appDelegate.ballValue isEqualToString:@"ironball"])
    {
        spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"iron_ball_strip.png"];
    }
    else if([appDelegate.ballValue isEqualToString:@"golfball"])
    {
        spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"golf_ball_strip.png"];
    }
    else if([appDelegate.ballValue isEqualToString:@"soccerball"])
    {
        spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"soccer_ball_strip.png"];
    }
    else if([appDelegate.ballValue isEqualToString:@"basketball"])
    {
        spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"basket_ball_strip.png"];
    }

    spriteSheet.position = ccp(hole1.position.x,60);
    [self addChild:spriteSheet];

    float frameWidth = 96;
    float frameHeight = 84;

    CCSprite *sprite = [CCSprite spriteWithTexture:spriteSheet.texture rect:CGRectMake(0, 0, frameWidth, frameHeight)];

    [spriteSheet addChild:sprite];

    //if(animation)
    {
        // create the animation
        CCAnimation *spriteAnimation = [CCAnimation animationWithName:@"potting" delay:0.1f];

        int frameCount = 0;
        for (int x = 0; x < 6; x++) 
        {
            // create an animation frame
            CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:spriteSheet.texture rect:CGRectMake(x*frameWidth,0*frameHeight,frameWidth,frameHeight) offset:ccp(0,0)];
            [spriteAnimation addFrame:frame];

            frameCount++;

            // stop looping after we've added 14 frames
            if (frameCount == 6)
            {
                //[self removeChild:spriteSheet cleanup:YES];
                break;
            }
        }

        // create the action
        CCAnimate *spriteAction = [CCAnimate actionWithAnimation:spriteAnimation];
        //CCRepeatForever *repeat = [CCRepeatForever actionWithAction:spriteAction];

        // run the action
        [sprite runAction:spriteAction];
        //[sprite runAction:repeat];
    }
    [self schedule:@selector(loading) interval:0.5];
    [self schedule:@selector(holeFinish) interval:1];
    //[self removeChild:spriteSheet cleanup:YES];
}

Любые предложения будут высоко оценены.

РЕДАКТИРОВАТЬ: То, что я нашел, проблема с линиями сгиба [self removeChild:ball1 cleanup:YES]; world->DestroyBody(ballBody); (МОЖЕТ быть).но, как это не всегда происходит (как я уже говорил), это смешно.

1 Ответ

2 голосов
/ 31 августа 2011

Я думаю, что ваша проблема заключается в том, что вы пытаетесь удалить тело, когда b2World «заблокирован», (когда мир занят обработкой столкновений).и удалив его в начале вашего следующего цикла:

Замените:

[self removeChild:ball1 cleanup:YES];
world->DestroyBody(ballBody);

на

ball1.isDead = YES;

И в начале вашего следующего игрового цикла:

for (Ball b in balls)
{
    if (b.isDead)
        world->DestroyBody(b.ballBody);
}
...