Player.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /**
  2. * one room arena
  3. * Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, version 3 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <cmath>
  18. #include <iostream>
  19. #include "Player.hpp"
  20. #include "Map.hpp"
  21. #include "Bullet.hpp"
  22. #include "Powerup.hpp"
  23. ActualPlayer* Player::actualPlayer;
  24. std::vector<AiPlayer*>* Player::aiPlayer;
  25. unsigned Player::totalScore = 0;
  26. Player::Player(Map* map):
  27. ConvexShape(6),
  28. _nukes(0),
  29. _speed(400.f),
  30. _strength(200),
  31. _rateOfFire(1.f),
  32. _map(map),
  33. _dead(false)
  34. {
  35. const int playerRadius = 30;
  36. const float angle = 40.f;
  37. this->setPoint(0, Vector2f(0, -playerRadius));
  38. this->setPoint(1, Vector2f(-std::sin(angle * 3.1415f / 180.f) * playerRadius / 3.25f, -std::cos(angle * 3.1415f / 180.f) * playerRadius / 3.f));
  39. this->setPoint(2, Vector2f(-std::sin(angle * 3.1415f / 180.f) * playerRadius, std::cos(angle * 3.1415f / 180.f) * playerRadius));
  40. this->setPoint(3, Vector2f(0, playerRadius / 4.f));
  41. this->setPoint(4, Vector2f(std::sin(angle * 3.1415f / 180.f) * playerRadius, std::cos(angle * 3.1415f / 180.f) * playerRadius));
  42. this->setPoint(5, Vector2f(std::sin(angle * 3.1415f / 180.f) * playerRadius / 3.25f, -std::cos(angle * 3.1415f / 180.f) * playerRadius / 3.f));
  43. this->setOutlineThickness(playerRadius * 6.f);
  44. _killKill.loadFromFile("data/explosion.ogg");
  45. _kill.setBuffer(_killKill);
  46. _laserLaser.loadFromFile("data/shoot.ogg");
  47. _laser.setBuffer(_laserLaser);
  48. _powerupPowerup.loadFromFile("data/powerup.ogg");
  49. _powerup.setBuffer(_powerupPowerup);
  50. }
  51. Player::~Player()
  52. {
  53. }
  54. void Player::setColor(Color color)
  55. {
  56. this->setFillColor(color);
  57. this->setOutlineColor(Color(color.r, color.g, color.b, 15));
  58. _color = color;
  59. }
  60. float mouseToRotation(Vector2f mouse)
  61. {
  62. float val = std::atan(-mouse.y / mouse.x) * 180.f / 3.1415f;
  63. if(mouse.x < 0.f)
  64. val += 180.f;
  65. else if(mouse.x > 0.f && mouse.y > 0.f)
  66. val += 360.f;
  67. val += 270.f;
  68. val = std::fmod(val, 360.f);
  69. val = 360.f - val;
  70. return val;
  71. }
  72. void ActualPlayer::input(float delta, Map* map, const Vector2f mouse)
  73. {
  74. static Clock clock;
  75. if(Mouse::isButtonPressed(Mouse::Left))
  76. {
  77. if(clock.getElapsedTime().asSeconds() >= _rateOfFire)
  78. {
  79. spawnBullet(false);
  80. clock.restart();
  81. }
  82. }
  83. bool left = Keyboard::isKeyPressed(Keyboard::A);
  84. bool right = Keyboard::isKeyPressed(Keyboard::D);
  85. bool up = Keyboard::isKeyPressed(Keyboard::W);
  86. bool down = Keyboard::isKeyPressed(Keyboard::S);
  87. float targetRotation = mouseToRotation(mouse);
  88. Transform transform;
  89. transform.translate(getPosition());
  90. transform.rotate(targetRotation);
  91. for(unsigned i = 0; i < getPointCount(); ++i)
  92. {
  93. Vector2f pos = transform.transformPoint(getPoint(i));
  94. if(map->collision(pos))
  95. break;
  96. if(i == getPointCount() - 1)
  97. setRotation(targetRotation);
  98. }
  99. static float velocityF = 0.f;
  100. static float velocityS = 0.f;
  101. static Vector2f movement;
  102. movement = movementHelper(delta, right, left, velocityS, getRotation() + 90.f, _speed, 0.75f) * delta;
  103. movement += movementHelper(delta, up, down, velocityF, getRotation(), _speed, 0.5f) * delta;
  104. for(unsigned i = 0; i < getPointCount(); ++i)
  105. {
  106. Vector2f pos = movement + getTransform().transformPoint(getPoint(i));
  107. if(map->collision(pos))
  108. {
  109. velocityF *= -1.f;
  110. velocityS *= -1.f;
  111. movement *= -1.f;
  112. break;
  113. }
  114. }
  115. move(movement);
  116. }
  117. void AiPlayer::updateAi(Map* map, ActualPlayer* player)
  118. {
  119. if(std::pow(player->getPosition().x - getPosition().x, 2) + std::pow(player->getPosition().y - getPosition().y, 2) < 1000*1000)
  120. {
  121. _targetRotation = mouseToRotation(Vector2f(player->getPosition().x - getPosition().x, player->getPosition().y - getPosition().y)) + _targetRotationDeviation;
  122. if(_nukes-- > 0)
  123. spawnBullet(true);
  124. else
  125. _nukes = 0;
  126. }
  127. else if(_powerupManager != nullptr)
  128. {
  129. for(unsigned i = 0; i < _powerupManager->getSize(); ++i)
  130. {
  131. if(std::pow(_powerupManager->getPowerup(i).getPosition().x - getPosition().x, 2) + std::pow(_powerupManager->getPowerup(i).getPosition().y - getPosition().y, 2) < 1000*1000)
  132. {
  133. _targetRotation = mouseToRotation(Vector2f(_powerupManager->getPowerup(i).getPosition().x - getPosition().x, _powerupManager->getPowerup(i).getPosition().y - getPosition().y)) + _targetRotationDeviation;
  134. }
  135. }
  136. }
  137. }
  138. void AiPlayer::input(float delta, Map* map, ActualPlayer* player)
  139. {
  140. if(_clock.getElapsedTime().asSeconds() >= _rateOfFire)
  141. {
  142. spawnBullet(false);
  143. _clock.restart();
  144. }
  145. if(_clock2.getElapsedTime().asSeconds() >= 0.5f)
  146. {
  147. updateAi(map, player);
  148. _clock2.restart();
  149. }
  150. Transform transform;
  151. transform.translate(getPosition());
  152. transform.rotate(_targetRotation);
  153. for(unsigned i = 0; i < getPointCount(); ++i)
  154. {
  155. Vector2f pos = transform.transformPoint(getPoint(i));
  156. if(map->collision(pos))
  157. break;
  158. if(i == getPointCount() - 1)
  159. setRotation(_targetRotation);
  160. }
  161. Vector2f movement;
  162. movement = movementHelper(delta, true, false, _velocity, getRotation(), _speed, 0.5f) * delta;
  163. for(unsigned i = 0; i < getPointCount(); ++i)
  164. {
  165. Vector2f pos = movement + getTransform().transformPoint(getPoint(i));
  166. if(map->collision(pos))
  167. {
  168. _velocity *= -1.f;
  169. movement *= -1.f;
  170. break;
  171. }
  172. }
  173. for(unsigned i = 0; i < getPointCount(); ++i)
  174. {
  175. Vector2f pos = movement * 100.f + getTransform().transformPoint(getPoint(i));
  176. if(map->collision(pos))
  177. {
  178. _targetRotation += delta * 720.f;
  179. _targetRotationDeviation += delta * 720.f;
  180. _targetRotation = std::fmod(_targetRotation, 360.f);
  181. _targetRotationDeviation = std::fmod(_targetRotationDeviation, 360.f);
  182. break;
  183. }
  184. if(i == getPointCount() - 1)
  185. _targetRotationDeviation = 0;
  186. }
  187. move(movement);
  188. _laser.setPosition(Vector3f(getPosition().x - player->getPosition().x, getPosition().y - player->getPosition().y, 0) / 100.f);
  189. _powerup.setPosition(Vector3f(getPosition().x - player->getPosition().x, getPosition().y - player->getPosition().y, 0) / 100.f);
  190. if(_kill.getStatus() != Sound::Playing)
  191. _kill.setPosition(Vector3f(getPosition().x - player->getPosition().x, getPosition().y - player->getPosition().y, 0) / 200.f);
  192. }
  193. void AiPlayer::registerPowerups(PowerupManager* mgr)
  194. {
  195. _powerupManager = mgr;
  196. }
  197. void Player::logic(float delta)
  198. {
  199. for(unsigned i = 0; i < _bullets.size(); ++i)
  200. {
  201. _bullets[i]->update(delta);
  202. if(_bullets[i]->isDead())
  203. {
  204. _bullets.erase(_bullets.begin() + i);
  205. if(_bullets[i]->isExplosive())
  206. {
  207. _kill.setPosition(Vector3f(0.f, 0.f, 0.f));
  208. _kill.play();
  209. }
  210. }
  211. }
  212. }
  213. void Player::spawnBullet(bool altFire)
  214. {
  215. if(!altFire)
  216. {
  217. _bullets.push_back(new RectBullet(getPosition(), getRotation(), _strength));
  218. _laser.play();
  219. }
  220. else
  221. {
  222. if(_nukes--)
  223. _bullets.push_back(new NukeBullet(getPosition(), getRotation(), _strength));
  224. else
  225. {
  226. _nukes = 0;
  227. return;
  228. }
  229. }
  230. if(this == actualPlayer)
  231. _bullets.back()->madeByPlayer();
  232. _bullets.back()->registerSelf(this);
  233. _bullets.back()->registerMap(_map);
  234. _bullets.back()->setColor(_color);
  235. }
  236. void Player::drawBullets(RenderTarget& target) const
  237. {
  238. for(unsigned i = 0; i < _bullets.size(); ++i)
  239. {
  240. target.draw(*_bullets[i]);
  241. }
  242. }
  243. void Player::hasten()
  244. {
  245. _powerup.play();
  246. _speed += 150.f;
  247. }
  248. void Player::addNuke()
  249. {
  250. _powerup.play();
  251. ++_nukes;
  252. }
  253. int Player::nukes() const
  254. {
  255. return _nukes;
  256. }
  257. void Player::growStronger()
  258. {
  259. if(_strength <= 600)
  260. {
  261. _powerup.play();
  262. _strength += 50;
  263. }
  264. }
  265. void Player::rateOfFire()
  266. {
  267. if(_rateOfFire > 0.2f)
  268. {
  269. _powerup.play();
  270. _rateOfFire -= 0.1f;
  271. }
  272. }
  273. void Player::kill(bool increaseScore)
  274. {
  275. totalScore += 1000 * increaseScore;
  276. _dead = true;
  277. _kill.play();
  278. }
  279. bool Player::isDead() const
  280. {
  281. return _dead;
  282. }
  283. Vector2f Player::movementHelper(float delta, bool key1, bool key2, float& velocity, float angle, float speed, float damping)
  284. {
  285. Vector2f rotated = Vector2f(std::sin(angle * 3.1415f / 180.f), -std::cos(angle * 3.1415f / 180.f));
  286. if(key1 && !key2)
  287. {
  288. if(velocity < speed)
  289. velocity += speed * delta;
  290. }
  291. else if(!key1 && key2)
  292. {
  293. if(velocity > -speed)
  294. velocity -= speed * delta;
  295. }
  296. else
  297. {
  298. if(std::fabs(velocity) < 50.f)
  299. velocity = 0.f;
  300. else if(velocity > 0.f)
  301. velocity -= speed * delta * damping;
  302. else
  303. velocity += speed * delta * damping;
  304. }
  305. return rotated * velocity;
  306. }