Box2d动态对象之间的碰撞

时间:2014-03-30 23:08:19

标签: ios objective-c cocos2d-iphone box2d kobold2d

我试图用Box2d做一个简单的射击游戏。

敌人和子弹都是动态的身体。我在屏幕的左侧创建敌人,然后对它们施加线性力使它们向右移动。玩家需要击中敌人三次才能杀死敌人。

我的问题是,如果前两次被子弹击中,我怎么能让敌人继续前进?现在,当敌人第一次被击中时,它将被击倒甚至被击倒出屏幕。我希望敌人只有在被杀(第三次被击中)时才会表现得像这样。我该怎么做?

感谢您的任何建议!

这里的一些代码:

    // Apply force
    rock.isFlying = 1;
    b2Vec2 force = b2Vec2(-2.0f*distance*cos,-2.0f*distance*sin);
    rockBody->ApplyForce(force,rockBody->GetWorldCenter());
    rockBody->SetLinearDamping(0.2f);

- (void)birdFly:(ccTime)dt{
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        ZLBird *myBird = (__bridge ZLBird*)b->GetUserData();
        if (b->GetUserData() != NULL && myBird.tag == TAG_BIRD)
        {
            // Apply force
            b2Vec2 gravityOffset;
            gravityOffset.x = 0;
            gravityOffset.y = myBird.multiplier*(myBird.startY - myBird.position.y);
            if (!myBird.isDead)
                b->ApplyForce(gravityOffset , b->GetWorldCenter());
        }
    }
}

void ContactListener::BeginContact(b2Contact* contact)
{
    b2Body* bodyA = contact->GetFixtureA()->GetBody();
    b2Body* bodyB = contact->GetFixtureB()->GetBody();
    CCSprite* spriteA = (__bridge CCSprite*)bodyA->GetUserData();
    CCSprite* spriteB = (__bridge CCSprite*)bodyB->GetUserData();

    if (spriteA != NULL && spriteB != NULL)
    {
        // if hit by rock
        if (spriteA.tag == -1 && spriteB.tag == TAG_BIRD){
            ZLBird *myBird = (__bridge ZLBird*)bodyB->GetUserData();
            ZLRock *myRock = (__bridge ZLRock*)bodyA->GetUserData();
            [myBird getHurt];
        }
        else if(spriteB.tag == -1 && spriteA.tag == TAG_BIRD) {
            ZLBird *myBird = (__bridge ZLBird*)bodyA->GetUserData();
            ZLRock *myRock = (__bridge ZLRock*)bodyB->GetUserData();
            [myBird getHurt];
        }
}
}

1 个答案:

答案 0 :(得分:1)

联系人侦听器中的preSolve和postSolve回调方法在这里会很有帮助。您可以在preSolve()方法中设置SetEnabled(false),以便box2d不会计算要在主体上应用的所需力。即box2d将跳过碰撞。但请注意,这仅适用于该特定时间步长。在下一个box2d时间步骤中,将计算碰撞。为了在前两次跳过岩石与鸟之间的完全碰撞,你需要在每一帧中调用SetEnabled(false),但需要检查。所以对于例如。

在摇滚体的用户数据中取一个整数。并且在每个时间步骤中,您只需调用SetEnabled(false)并递增整数,直到整数变为2.一旦这是2,则下次再调用SetEnabled(false)。默认情况下,它将设置为SetEnabled(true)。在第三次击中时,box2d将对岩体施加力。

您必须阅读http://www.iforce2d.net/b2dtut/collision-anatomy

具体阅读preSolve和postSolve回调。