Car.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. # include "Car.h"
  2. Car::Car()
  3. :m_imgCar( 0x0 ), m_imgWheel( 0x0 ),
  4. m_bodyCar( 0x0 ),
  5. m_cmd( FREE ),
  6. m_currentTorque( 0.0f ), m_currentSpeed( 0.0f ), m_sense( 1.0f ), m_latence( 40.0f ),
  7. m_goTorque( 0.9f ), m_minTorque( 0.0025f ), m_maxSpeed( 60.0f )
  8. {
  9. // Constructeur
  10. m_currentTorque = m_minTorque ;
  11. m_currentSpeed = 0.0f ;
  12. }
  13. Car::~Car()
  14. {
  15. if ( !m_imgCar )
  16. SDL_FreeSurface( m_imgCar );
  17. if ( !m_imgWheel )
  18. SDL_FreeSurface( m_imgWheel );
  19. }
  20. void Car::destroy( b2World &world )
  21. {
  22. /// Détruire les liaisons
  23. // Les moteurs
  24. while ( !m_motorAxe.empty() )
  25. {
  26. world.DestroyJoint( m_motorAxe.back() );
  27. m_motorAxe.back() = nullptr;
  28. m_motorAxe.pop_back();
  29. }
  30. // Les roues libres
  31. while ( !m_fwdAxe.empty() )
  32. {
  33. world.DestroyJoint( m_fwdAxe.back() );
  34. m_fwdAxe.back() = nullptr;
  35. m_fwdAxe.pop_back();
  36. }
  37. /// Détruire les entités
  38. // Les roues
  39. while ( !m_bodyWheel.empty() )
  40. {
  41. world.DestroyBody( m_bodyWheel.back() );
  42. m_bodyWheel.back() = nullptr;
  43. m_bodyWheel.pop_back();
  44. }
  45. // Le carénage
  46. if ( m_bodyCar )
  47. world.DestroyBody( m_bodyCar );
  48. m_bodyCar = nullptr;
  49. }
  50. void Car::drive( command cmd )
  51. {
  52. // Commande
  53. m_cmd = cmd ;
  54. // Actions
  55. if ( m_cmd == FREE )
  56. {
  57. m_currentSpeed = 0.0f ;
  58. m_currentTorque = m_minTorque ;
  59. }
  60. else if ( m_cmd == BREAK )
  61. {
  62. m_currentSpeed = 0.0f ;
  63. m_currentTorque = m_goTorque ;
  64. }
  65. else if ( m_cmd == GO )
  66. {
  67. m_sense = -1.0f ;
  68. m_currentSpeed = m_maxSpeed ;
  69. m_currentTorque = m_goTorque / 20.0f ;
  70. }
  71. else if ( m_cmd == REVERSE )
  72. {
  73. m_sense = 0.5f ;
  74. m_currentSpeed = m_maxSpeed ;
  75. m_currentTorque = m_goTorque / 20.0f ;
  76. }
  77. }
  78. void Car::jump( float correction )
  79. {
  80. // Jump
  81. b2Vec2 spring;
  82. spring.Set( 0.0f, -1.7f );
  83. m_bodyCar->ApplyLinearImpulseToCenter( spring, true );
  84. // Correction
  85. m_bodyCar->ApplyAngularImpulse( - m_bodyCar->GetAngle() * correction, true );
  86. }
  87. void Car::spin( float tq )
  88. {
  89. // Couple sur le carénage
  90. m_bodyCar->ApplyAngularImpulse( tq, true );
  91. }
  92. void Car::update()
  93. {
  94. // Update state
  95. if ( m_cmd == GO || m_cmd == REVERSE )
  96. {
  97. m_currentTorque = ( m_latence * m_currentTorque + m_goTorque ) / ( m_latence + 1.0f ) ;
  98. }
  99. // Update motor
  100. for ( unsigned int i(0); i < m_motorAxe.size() ; i++ )
  101. {
  102. m_motorAxe[i]->SetMotorSpeed( m_sense * m_currentSpeed );
  103. m_motorAxe[i]->SetMaxMotorTorque( m_currentTorque );
  104. }
  105. }
  106. b2Vec2 Car::GetPosition()
  107. {
  108. return m_bodyCar->GetPosition();
  109. }
  110. b2Vec2 Car::GetVelocity()
  111. {
  112. return m_bodyCar->GetLinearVelocity();
  113. }
  114. float Car::GetTorque()
  115. {
  116. return m_currentTorque;
  117. }
  118. float Car::GetSpeed()
  119. {
  120. return m_currentSpeed;
  121. }
  122. bool Car::GetIsOnGround()
  123. {
  124. bool rep( false );
  125. for ( b2ContactEdge* ce( m_bodyWheel.front()->GetContactList() ); ce && !rep; ce = ce->next )
  126. rep = ce->contact->IsTouching() ;
  127. return rep;
  128. }
  129. void Car::createMotorWheel( b2World &world, b2Vec2 rel, float friction, float density )
  130. {
  131. // Vérifie la présence d'image
  132. if ( m_imgWheel == 0x0 )
  133. {
  134. std::cout << "Car::createMotorWheel > pas d'image." << std::endl ;
  135. return ;
  136. }
  137. // Vérifie la présence de carénage
  138. if ( m_bodyCar == 0x0 )
  139. {
  140. std::cout << "Car::createMotorWheel > pas de carénage." << std::endl ;
  141. return ;
  142. }
  143. // Dimensions
  144. float rwheel;
  145. rwheel = (float)m_imgWheel->h / MULTI / 2 ;
  146. // Définition body
  147. b2BodyDef bodyDef;
  148. b2CircleShape dynamicCircle;
  149. b2FixtureDef fixtureDef;
  150. bodyDef.type = b2_dynamicBody;
  151. // Roue moteur
  152. bodyDef.userData.pointer = (uintptr_t) m_imgWheel ;
  153. bodyDef.position = m_bodyCar->GetPosition() + rel ;
  154. dynamicCircle.m_radius = rwheel ;
  155. fixtureDef.shape = &dynamicCircle;
  156. fixtureDef.density = density;
  157. fixtureDef.friction = friction;
  158. m_bodyWheel.push_back( world.CreateBody(&bodyDef) );
  159. m_bodyWheel.back()->CreateFixture(&fixtureDef);
  160. // Création pivot arrière
  161. b2RevoluteJointDef myJointDef;
  162. myJointDef.collideConnected = false ;
  163. myJointDef.Initialize( m_bodyWheel.back(), m_bodyCar, m_bodyWheel.back()->GetPosition() );
  164. myJointDef.maxMotorTorque = 0.05f;
  165. myJointDef.motorSpeed = 0.0f;
  166. myJointDef.enableMotor = true;
  167. m_motorAxe.push_back( (b2RevoluteJoint*)world.CreateJoint(&myJointDef) );
  168. // Fin
  169. return ;
  170. }
  171. void Car::createFreeWheel( b2World &world, b2Vec2 rel, float friction, float density )
  172. {
  173. // Vérifie la présence d'image
  174. if ( m_imgWheel == 0x0 )
  175. {
  176. std::cout << "Car::createFreeWheel > pas d'image." << std::endl ;
  177. return ;
  178. }
  179. // Vérifie la présence de carénage
  180. if ( m_bodyCar == 0x0 )
  181. {
  182. std::cout << "Car::createFreeWheel > pas de carénage." << std::endl ;
  183. return ;
  184. }
  185. // Dimensions
  186. float rwheel;
  187. rwheel = (float)m_imgWheel->h / MULTI / 2 ;
  188. // Définition body
  189. b2BodyDef bodyDef;
  190. b2CircleShape dynamicCircle;
  191. b2FixtureDef fixtureDef;
  192. bodyDef.type = b2_dynamicBody;
  193. // Roue avant
  194. bodyDef.userData.pointer = (uintptr_t) m_imgWheel ;
  195. bodyDef.position = m_bodyCar->GetPosition() + rel ;
  196. dynamicCircle.m_radius = rwheel ;
  197. fixtureDef.shape = &dynamicCircle;
  198. fixtureDef.density = density;
  199. fixtureDef.friction = friction;
  200. m_bodyWheel.push_back( world.CreateBody(&bodyDef) );
  201. m_bodyWheel.back()->CreateFixture(&fixtureDef);
  202. // Création pivot avant
  203. b2RevoluteJointDef myJointDef;
  204. myJointDef.collideConnected = false ;
  205. myJointDef.Initialize( m_bodyWheel.back(), m_bodyCar, m_bodyWheel.back()->GetPosition() );
  206. m_fwdAxe.push_back( (b2RevoluteJoint*)world.CreateJoint(&myJointDef) );
  207. // Fin
  208. return ;
  209. }
  210. void Car::createCarenage( b2World &world, float x, float y, float friction, float density )
  211. {
  212. // Vérifie si présence de carénage
  213. if ( m_bodyCar != 0x0 )
  214. {
  215. world.DestroyBody( m_bodyCar );
  216. m_bodyCar = 0x0 ;
  217. }
  218. // Dimensions
  219. float wtruck, htruck ;
  220. wtruck = (float)m_imgCar->w / MULTI / 2 ;
  221. htruck = (float)m_imgCar->h / MULTI / 2 ;
  222. // Définition body
  223. b2BodyDef bodyDef;
  224. b2PolygonShape dynamicBox;
  225. b2FixtureDef fixtureDef;
  226. bodyDef.type = b2_dynamicBody;
  227. // Carrosserie
  228. bodyDef.userData.pointer = (uintptr_t) m_imgCar ;
  229. bodyDef.position.Set( x, y );
  230. dynamicBox.SetAsBox( wtruck, htruck );
  231. fixtureDef.shape = &dynamicBox;
  232. fixtureDef.density = density;
  233. fixtureDef.friction = friction;
  234. m_bodyCar = world.CreateBody( &bodyDef );
  235. m_bodyCar->CreateFixture( &fixtureDef );
  236. }