Missiles.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. # include "Missiles.h"
  2. /*
  3. - Passer le plane pour update
  4. - Faire une fonction de création commune
  5. */
  6. void updateMissiles( b2World &world, b2Body* target, bool foresee )
  7. {
  8. // Variables
  9. Entity* descr( nullptr );
  10. bool boom(false) ;
  11. std::vector<b2Body*> dustbin;
  12. // Force de correction
  13. b2Vec2 to( target->GetPosition() );
  14. b2Vec2 force;
  15. float d;
  16. // Parcours des entités
  17. for ( b2Body* b( world.GetBodyList() ); b; b = b->GetNext() )
  18. {
  19. // Description de l'entité
  20. descr = (Entity*)b->GetUserData().pointer;
  21. // Skip entités non missile
  22. if ( descr == 0x0 || descr->id == LAND || descr->id == PLANE )
  23. continue ;
  24. // Anticipation du mouvement de la cible
  25. if ( foresee )
  26. to = anticipate( b, target );
  27. // Trajectoire des missiles
  28. switch ( descr->id )
  29. {
  30. case INERT :
  31. case ANG :
  32. break;
  33. case ARROW :
  34. force = to - b->GetPosition();
  35. force.Normalize();
  36. force *= 0.0005f ;
  37. b->ApplyLinearImpulseToCenter( force, true );
  38. break;
  39. case CHARGE :
  40. force = to - b->GetPosition();
  41. d = force.Length() + 0.1f;
  42. force.Normalize();
  43. force *= 0.0005f / d / d ;
  44. b->ApplyLinearImpulseToCenter( force, true );
  45. break;
  46. default:
  47. std::cout << "Missile sans protocole de guidage." << std::endl;
  48. continue ;
  49. break ;
  50. }
  51. // Test de collision
  52. boom = false;
  53. for ( b2ContactEdge* ce( b->GetContactList() ); ce && !boom; ce = ce->next )
  54. boom = ce->contact->IsTouching() ;
  55. if ( boom )
  56. dustbin.push_back(b);
  57. }
  58. // Destruction des missiles détruits
  59. for ( unsigned int k(0); k < dustbin.size(); k++ )
  60. {
  61. delete (Entity*)dustbin[k]->GetUserData().pointer;
  62. world.DestroyBody( dustbin[k] );
  63. dustbin[k] = nullptr;
  64. }
  65. }
  66. void createInert( b2Vec2 from, b2Body* target, b2World &world, Identity missile )
  67. {
  68. // Body
  69. b2BodyDef bodyDef;
  70. bodyDef.position = from;
  71. bodyDef.userData.pointer = (uintptr_t) new Entity( {0.01f, missile} );
  72. bodyDef.type = b2_dynamicBody;
  73. bodyDef.linearDamping = 0.01f;
  74. bodyDef.fixedRotation = true ;
  75. b2Body* body = world.CreateBody(&bodyDef);
  76. // Shape
  77. b2CircleShape dynamicCircle;
  78. dynamicCircle.m_radius = 0.01f ;
  79. b2FixtureDef fixtureDef;
  80. fixtureDef.shape = &dynamicCircle;
  81. fixtureDef.density = 10.0f;
  82. fixtureDef.friction = 0.3f;
  83. body->CreateFixture(&fixtureDef);
  84. // Force de départ
  85. b2Vec2 to( target->GetPosition() );
  86. b2Vec2 force;
  87. switch ( missile )
  88. {
  89. default :
  90. break ;
  91. case INERT :
  92. force = to - from;
  93. force.Normalize();
  94. force *= 0.01f ;
  95. body->ApplyLinearImpulseToCenter( force, true );
  96. break ;
  97. case ANG :
  98. force = target->GetLinearVelocity();
  99. force *= (to - from).Length();
  100. force *= 0.33f ;
  101. force += to - from;
  102. force.Normalize();
  103. force *= 0.01f ;
  104. body->ApplyLinearImpulseToCenter( force, true );
  105. break;
  106. case ARROW :
  107. case CHARGE :
  108. break;
  109. }
  110. }
  111. b2Vec2 anticipate( b2Body* missile, b2Body* target )
  112. {
  113. // Vecteur entre le missile et la cible
  114. b2Vec2 destination( target->GetPosition() - missile->GetPosition() );
  115. float distance( destination.Length() );
  116. destination *= ( 1.0f / distance );
  117. // Données sur le missile
  118. b2Vec2 vMissile_vec( missile->GetLinearVelocity() );
  119. // Vitesse d'approche
  120. float incoming( b2Dot(vMissile_vec, destination) );
  121. if ( incoming == 0.0f )
  122. return target->GetPosition() ;
  123. // Temps d'approche
  124. float tau( distance / incoming );
  125. // Données de la cible
  126. b2Vec2 vPlane_vec( target->GetLinearVelocity() );
  127. // Réponse
  128. b2Vec2 rep( target->GetPosition() + tau * vPlane_vec );
  129. // Fin du calcul
  130. return rep;
  131. }