2017-08-11 7 views
2

J'ai un peu de mal comme le dit le titre: je n'arrive pas à comprendre comment tirer la balle dans la direction indiquée par le pistolet.Box2D - Tir de la mitrailleuse tournante

Picture of problem

Voici le code version courte, pour mon tir de balle:

b2BodyDef bd; 
bd.type = b2_dynamicBody; 
bd.bullet = true; 
bd.position = gun->GetPosition();//bullet start at the middle of the gun 
m_bullet = m_world->CreateBody(&bd); 
m_bullet->CreateFixture(&fd);   
m_bullet->ApplyLinearImpulseToCenter(??? ,true); 

Au début, je pensais que le premier paramètre est la direction que vous voulez que le corps se dirigent vers si je mets dans gun->GetWorldPoint(b2Vec2(0.0f,-5.0f)) (milieu de la le museau des armes à feu). Gros manque! Après un moment, j'ai pensé que je devrais essayer de mettre dans le vecteur de degrés de rotation de l'arme actuelle b2Vec2 vect = b2Vec2(cos(angle * PI/180), sin(angle * PI/180)); mais la balle ne volera pas du tout. Maintenant, je suis à court d'idées. S'il te plaît, de la lumière.

Version complète du code:

public: 
b2Body* m_bullet = NULL; 
b2Body* gun; 
b2RevoluteJoint* joint1; 
b2FixtureDef fd; 

TestingStuff() 
{ 
    { 
     //body 
     b2CircleShape circle1; 
     circle1.m_radius = 1.6f; 

     fd.shape = &circle1; 
     fd.density = 1.0f; 
     fd.filter.groupIndex = -1;   

     b2BodyDef bd1; 
     bd1.type = b2_staticBody; 
     bd1.position.Set(-5.0f, 9.0f); 
     b2Body* body1 = m_world->CreateBody(&bd1); 
     body1->CreateFixture(&fd); 

     //gun 
     b2PolygonShape box; 
     box.SetAsBox(0.5f, 5.0f); 

     fd.shape = &box; 
     fd.density = 1.0f; 
     fd.filter.groupIndex = -1; 

     b2BodyDef bd2; 
     bd2.type = b2_dynamicBody; 
     bd2.position.Set(-5.0f, 8.0f); 
     gun = m_world->CreateBody(&bd2); 
     gun->CreateFixture(&fd); 

     //joint 
     b2RevoluteJointDef jd1; 
     jd1.Initialize(gun, body1, bd1.position); 
     jd1.enableMotor = true; 
     jd1.maxMotorTorque = 90; 
     jd1.motorSpeed = 180 * DEGTORAD;//DEGTORAD=0.0174532925199432957f 
     joint1 = (b2RevoluteJoint*) m_world->CreateJoint(&jd1); 
    } 

} 

void Keyboard(int key) 
{ 
    switch (key) 
    { 
    case GLFW_KEY_COMMA: 
     if (m_bullet != NULL) 
     { 
      m_world->DestroyBody(m_bullet); 
      m_bullet = NULL; 
     } 

     { 
      //bullet 
      b2CircleShape shape; 
      shape.m_radius = 0.25f; 

      fd.shape = &shape; 
      fd.density = 1; 
      fd.restitution = 0.05f; 
      fd.filter.groupIndex = -1; 

      b2BodyDef bd; 
      bd.type = b2_dynamicBody; 
      bd.bullet = true; 
      bd.position = gun->GetPosition(); 
      m_bullet = m_world->CreateBody(&bd); 
      m_bullet->CreateFixture(&fd); 
      m_bullet->ApplyLinearImpulseToCenter(??? ,true); 
     } 
     break; 
    } 
} 
+1

"' b2Vec2 (cos (angle * PI/180), sin (angle)) '", est 'angle' en radians ou pas? – genpfault

+0

@genpfault: pour 90 degrés, je vais mettre l'angle = 90.0f – Dant

+0

Je suppose que j'essaie de préciser que vous n'avez pas converti l'argument 'sin()' en radians, seulement 'cos()' ' s. Vous devez faire les deux sinon les résultats seront sans signification, ou au moins un billet aller simple pour Funkytown. – genpfault

Répondre

1

Après une bonne nuit de sommeil j'ai trouvé la solution après quelques autres essais et d'erreurs.

//bullet 
float degAngle = joint1->GetJointAngle() * RADTODEG + 180; 
b2Vec2 vect = b2Vec2(sin(degAngle* (b2_pi/180)) * 10, cos(degAngle* (b2_pi/180)) * 10); 
m_bullet->ApplyLinearImpulseToCenter(vect ,true); 

Le * 10 est d'augmenter l'impulsion, faire la balle voler plus vite et plus loin, pour des raisons de test, je viens fais 10. Notez que ce code est juste pour le test, si vous voulez faire plus réaliste, augmentez l'impulsion et faites avancer la balle vers le museau au lieu d'aller vers le vecteur dans lequel elle a été tirée.