动态对象之间的Box2d碰撞

问题描述:

我正在试图用Box2d做一个简单的射击游戏。动态对象之间的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]; 
     } 
} 
} 
+0

我们可以看到一些代码吗? – Roecrew

+0

当然!我刚刚编辑了这个问题。 – alanlzl

+0

我可以看到getHurt方法吗? – Roecrew

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回调。