123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- # 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<b2Body*> 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;
- }
|