# include "Missiles.h" /* - Passer le plane pour update - Faire une fonction de création commune */ void updateMissiles( b2World &world, b2Body* target, bool foresee ) { // Variables Entity* descr( nullptr ); bool boom(false) ; std::vector dustbin; // Force de correction b2Vec2 to( target->GetPosition() ); b2Vec2 force; float d; // Parcours des entités for ( b2Body* b( world.GetBodyList() ); b; b = b->GetNext() ) { // Description de l'entité descr = (Entity*)b->GetUserData().pointer; // Skip entités non missile if ( descr == 0x0 || descr->id == LAND || descr->id == PLANE ) continue ; // Anticipation du mouvement de la cible if ( foresee ) to = anticipate( b, target ); // Trajectoire des missiles switch ( descr->id ) { case INERT : case ANG : break; case ARROW : force = to - b->GetPosition(); force.Normalize(); force *= 0.0005f ; b->ApplyLinearImpulseToCenter( force, true ); break; case CHARGE : force = to - b->GetPosition(); d = force.Length() + 0.1f; force.Normalize(); force *= 0.0005f / d / d ; b->ApplyLinearImpulseToCenter( force, true ); break; default: std::cout << "Missile sans protocole de guidage." << std::endl; continue ; break ; } // Test de collision boom = false; for ( b2ContactEdge* ce( b->GetContactList() ); ce && !boom; ce = ce->next ) boom = ce->contact->IsTouching() ; if ( boom ) dustbin.push_back(b); } // Destruction des missiles détruits for ( unsigned int k(0); k < dustbin.size(); k++ ) { delete (Entity*)dustbin[k]->GetUserData().pointer; world.DestroyBody( dustbin[k] ); dustbin[k] = nullptr; } } void createInert( b2Vec2 from, b2Body* target, b2World &world, Identity missile ) { // Body b2BodyDef bodyDef; bodyDef.position = from; bodyDef.userData.pointer = (uintptr_t) new Entity( {0.01f, missile} ); bodyDef.type = b2_dynamicBody; bodyDef.linearDamping = 0.01f; bodyDef.fixedRotation = true ; b2Body* body = world.CreateBody(&bodyDef); // Shape b2CircleShape dynamicCircle; dynamicCircle.m_radius = 0.01f ; b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicCircle; fixtureDef.density = 10.0f; fixtureDef.friction = 0.3f; body->CreateFixture(&fixtureDef); // Force de départ b2Vec2 to( target->GetPosition() ); b2Vec2 force; switch ( missile ) { default : break ; case INERT : force = to - from; force.Normalize(); force *= 0.01f ; body->ApplyLinearImpulseToCenter( force, true ); break ; case ANG : force = target->GetLinearVelocity(); force *= (to - from).Length(); force *= 0.33f ; force += to - from; force.Normalize(); force *= 0.01f ; body->ApplyLinearImpulseToCenter( force, true ); break; case ARROW : case CHARGE : break; } } b2Vec2 anticipate( b2Body* missile, b2Body* target ) { // Vecteur entre le missile et la cible b2Vec2 destination( target->GetPosition() - missile->GetPosition() ); float distance( destination.Length() ); destination *= ( 1.0f / distance ); // Données sur le missile b2Vec2 vMissile_vec( missile->GetLinearVelocity() ); // Vitesse d'approche float incoming( b2Dot(vMissile_vec, destination) ); if ( incoming == 0.0f ) return target->GetPosition() ; // Temps d'approche float tau( distance / incoming ); // Données de la cible b2Vec2 vPlane_vec( target->GetLinearVelocity() ); // Réponse b2Vec2 rep( target->GetPosition() + tau * vPlane_vec ); // Fin du calcul return rep; }