Soldier.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //
  2. // Created by jovian on 18/07/17.
  3. //
  4. #include <iostream>
  5. #include "Soldier.h"
  6. #include "b2Angle.h"
  7. Soldier::Soldier(Faction faction, Controller *ctrl, TinyWorld *tinyWorld,
  8. unsigned int imgId, unsigned int camp, unsigned int life)
  9. : Entity(faction, imgId, tinyWorld),
  10. m_ctrl(ctrl), m_camp(camp), m_life(life), m_tinyWorld(tinyWorld), m_homeFixture(nullptr),
  11. m_forceScale(50.0f), m_jumpVec(0.0f, -500.0f), m_jumpVelocityLimit(-0.5f),
  12. m_cool(0), m_coolCeil(10) {
  13. // Set the correct image
  14. if (imgId == 0) {
  15. if (m_camp == 0)
  16. m_imgId = 1;
  17. else if (m_camp == 1)
  18. m_imgId = 13;
  19. }
  20. }
  21. void Soldier::shoot(const b2Vec2 &dir) {
  22. m_cool = 0;
  23. m_tinyWorld->addEntity(new Bullet(m_body->GetPosition(), m_tinyWorld, dir, m_body->GetLinearVelocity(), m_camp));
  24. }
  25. void Soldier::update() {
  26. // Life exist
  27. if (m_life == 0)
  28. m_exist = false;
  29. // todo A soldier fell out the world
  30. if (m_body->GetPosition().y > 100.0f)
  31. m_exist = false;
  32. // Firing
  33. m_cool++;
  34. if (m_ctrl->isFiring() && m_cool > m_coolCeil)
  35. shoot(m_ctrl->getVisor()); // todo Ship alignement
  36. // todo Shield activation
  37. // Movement
  38. b2Vec2 move(b2Dir(m_body->GetAngle() - b2_pi * 0.5f));
  39. move.x *= m_forceScale * m_ctrl->getAcceleration();
  40. move.y *= m_forceScale * m_ctrl->getAcceleration();
  41. m_body->ApplyForceToCenter(move, true);
  42. // Torque with buttons
  43. #define TORQUE_MULTI_BUT 0.005f
  44. m_body->ApplyAngularImpulse(m_ctrl->getTorque() * TORQUE_MULTI_BUT, true);
  45. // Torque with visor
  46. #define TORQUE_MULTI_STICK 0.022f
  47. float deltaAngle = m_body->GetAngle() - b2Angle(m_ctrl->getVisor()) - b2_pi * 0.5f;
  48. while (deltaAngle > b2_pi)
  49. deltaAngle -= b2_pi * 2.0f;
  50. while (deltaAngle < -b2_pi)
  51. deltaAngle += b2_pi * 2.0f;
  52. m_body->ApplyAngularImpulse(-deltaAngle * TORQUE_MULTI_STICK, true);
  53. // todo Boosting
  54. if (isTouching()
  55. && m_ctrl->isBoosting()
  56. && m_body->GetLinearVelocity().y > m_jumpVelocityLimit) {
  57. m_body->ApplyForceToCenter(m_jumpVec, true);
  58. }
  59. // Damage taken by bullet
  60. for (b2ContactEdge *ce = m_body->GetContactList(); ce; ce = ce->next) {
  61. b2Contact *c = ce->contact;
  62. // Get incoming fixture
  63. b2Fixture *incomingFixture(c->GetFixtureA());
  64. if (incomingFixture == m_homeFixture)
  65. incomingFixture = c->GetFixtureB();
  66. // Detect bullet presence
  67. Entity *incomingEntity((Entity *) incomingFixture->GetBody()->GetUserData().pointer);
  68. if (incomingEntity->getFaction() == BULLET) {
  69. // Damage
  70. Bullet *incomingBullet((Bullet*)incomingEntity);
  71. int damage(incomingBullet->getDamage());
  72. if (m_life < damage)
  73. m_life = 0;
  74. else
  75. m_life -= damage;
  76. // Bullet destroyed
  77. incomingEntity->setExistence(false);
  78. }
  79. }
  80. }
  81. void Soldier::createPhysicalShape(b2Vec2 spawn) {
  82. // Already exists ?
  83. if (m_body != nullptr) {
  84. std::cout << "Soldier::createPhysicalShape() > Body non null pointer. Creation aborted." << std::endl;
  85. return;
  86. }
  87. // Creation of physical body
  88. b2BodyDef bodyDef;
  89. bodyDef.type = b2_dynamicBody;
  90. bodyDef.position = spawn;
  91. bodyDef.fixedRotation = false;
  92. bodyDef.linearDamping = 1.0f;
  93. bodyDef.angularDamping = 10.0f;
  94. m_body = m_tinyWorld->CreateBody(&bodyDef);
  95. // Creation of super shape
  96. b2Vec2 vertices[5];
  97. vertices[0].Set(0.0f, -28.0f / DEFAULT_ZOOM);
  98. vertices[1].Set(-26.0f / DEFAULT_ZOOM, 14.0f / DEFAULT_ZOOM);
  99. vertices[2].Set(-25.0f / DEFAULT_ZOOM, 28.0f / DEFAULT_ZOOM);
  100. vertices[3].Set(25.0f / DEFAULT_ZOOM, 28.0f / DEFAULT_ZOOM);
  101. vertices[4].Set(26.0f / DEFAULT_ZOOM, 14.0f / DEFAULT_ZOOM);
  102. b2PolygonShape allyShape;
  103. allyShape.Set(vertices, 5);
  104. // Definition of fixture
  105. b2FixtureDef fixtureDef;
  106. fixtureDef.shape = &allyShape;
  107. fixtureDef.density = 6.0f;
  108. fixtureDef.friction = 0.3f;
  109. // Fixture filtering
  110. if (m_camp == 0) {
  111. fixtureDef.filter.categoryBits = 0b0001;
  112. fixtureDef.filter.maskBits = 0b1101;
  113. } else if (m_camp == 1) {
  114. fixtureDef.filter.categoryBits = 0b0100;
  115. fixtureDef.filter.maskBits = 0b0111;
  116. }
  117. // Creation of fixture
  118. m_homeFixture = m_body->CreateFixture(&fixtureDef);
  119. // Link this soldier
  120. establishPhysicalLink();
  121. }