【问题标题】:Cocos2d game termination problem when a moving sprite goes inside the bounding box of a animating still sprite(a ball get into a hole)Cocos2d 游戏终止问题,当移动精灵进入动画静止精灵的边界框时(球进入洞)
【发布时间】:2011-08-27 06:08:45
【问题描述】:

让我深入解释一下,当if(CGRectContainsPoint([hole1 boundingBox], ball1.position)) 条件成立时,我会做很多事情,比如计划外、选择器、破坏球体调用动画(请参考下面的代码 )ETC。这在大多数情况下都能正常工作。但有时当球真的接近球洞时(只是接触球洞但不足以使上述条件成立),或者被以非常快的速度抛向球洞,则应用程序被终止。我已经通过评论在本节中执行的许多操作进行了检查,但没有任何帮助,当采取一些措施使其终止时,应用程序会继续终止。

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); 后面的行有问题(可能是)。但由于它并不总是发生,(正如我所提到的),因此它很荒谬。

【问题讨论】:

  • 我建议你设置它,这样你就可以精确地重复球的相同运动,这样它每次都会崩溃,然后开始注释掉部分代码。这至少会告诉你它崩溃的地方,否则很难猜出发生了什么。
  • 哦,是的,我做到了,但它没有帮助,实际上当球被抛出时,很快就会出现这个问题。
  • 那么,当问题发生时,崩溃日志/堆栈跟踪消息是什么
  • 嗯,这确实是个问题 :) 我不熟悉 cocos2d,所以我无法对此发表评论,但您需要进一步缩小问题范围,或者最好获取堆栈跟踪,否则任何人都很难猜到发生了什么。
  • 是的,我正在尽最大努力解决它,我得到的唯一解决方案是评论完整的代码(哈哈),所以我发现以下行有问题[self removeChild:ball1 cleanup:YES]; world-&gt;DestroyBody(ballBody); (或许)。但由于它并不总是发生,(正如我所提到的),因此这很荒谬。

标签: iphone cocos2d-iphone box2d termination


【解决方案1】:

我认为您的问题将是当 b2World 被“锁定”时(当世界忙于解决碰撞时)您试图删除一个主体。

尝试将对象标记为准备删除,并在下一个循环开始时将其删除:

替换:

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

ball1.isDead = YES;

在下一个游戏循环开始时:

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

【讨论】:

  • 但是正如你所看到的,我使用了一个灌入球的动画,所以我认为如果我不移除球会看起来很糟糕。有什么建议吗?
  • 我并不是建议你不要移除球,只是不要在同一帧中移除它。当世界未锁定时,在下一帧开始时将其移除。在 60 fps 时,仅延迟 0.016 秒
  • 如果我不破坏球怎么办?
猜你喜欢
  • 1970-01-01
  • 2011-11-15
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
相关资源
最近更新 更多