代码之家  ›  专栏  ›  技术社区  ›  alanlzl

动态对象之间的Box2d碰撞

  •  0
  • alanlzl  · 技术社区  · 10 年前

    我想用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 回复  |  直到 10 年前
        1
  •  1
  •   SaffronState    10 年前

    联系人侦听器中的preSolve和postSolve回调方法将在这里有所帮助。您可以在preSolve()方法中设置SetEnabled(false),这样box2d就不会计算要施加在物体上的所需力。即盒2d将跳过冲突。但请注意,这仅适用于特定的时间步长持续时间。在下一个框2d时间步中,将计算碰撞。为了在前两次跳过岩石和鸟之间的完全碰撞,您需要在每一帧中调用SetEnabled(false),但需要进行检查。例如。

    在岩石体的userdata中取一个整数。在每个时间步骤中,只需调用SetEnabled(false)并递增整数,直到整数变为2。一旦这是2,则下次以后不要调用SetEnabled(false)。默认情况下,它将设置为SetEnabled(true)。在第三次撞击时,盒子2d将在岩石上施加力。

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

    具体阅读preSolve和postSolve回调。