Bullet.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * Triangles
  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 "Bullet.hpp"
  18. #include "Utility.hpp"
  19. #include "cmath"
  20. Bullet::Bullet(float rotation, sf::Vector2f initialPosition, sf::SoundBuffer& buffer1, sf::SoundBuffer& buffer2, Foreground* foreground): _texture(nullptr), _foreground(foreground), _hit(false), _dead(false)
  21. {
  22. setRotation(rotation);
  23. setPosition(initialPosition);
  24. _vertex[0].position = sf::Vector2f(-3.f, 40.f);
  25. _vertex[1].position = sf::Vector2f(3.f, 40.f);
  26. _vertex[2].position = sf::Vector2f(3.f, -40.f);
  27. _vertex[3].position = sf::Vector2f(-3.f, -40.f);
  28. _sound.setBuffer(buffer1);
  29. _explosion.setBuffer(buffer2);
  30. _sound.play();
  31. genCollisionBox("data/hitbox/Bullet.png", sf::Vector2f(3.f, 40.f));
  32. }
  33. void Bullet::setTexture(sf::Texture& texture)
  34. {
  35. _texture = &texture;
  36. sf::Vector2u size = texture.getSize();
  37. _vertex[0].texCoords = sf::Vector2f(0, size.y);
  38. _vertex[1].texCoords = sf::Vector2f(size.x, size.y);
  39. _vertex[2].texCoords = sf::Vector2f(size.x / 2.f, 0);
  40. _vertex[3].texCoords = sf::Vector2f(size.x / 2.f, size.y / 2.f);
  41. }
  42. void Bullet::draw(sf::RenderTarget& target, sf::RenderStates states) const
  43. {
  44. if(_hit)
  45. return;
  46. states.transform *= getTransform();
  47. if(_texture != nullptr)
  48. states.texture = (_texture);
  49. target.draw(_vertex, 4, sf::Quads, states);
  50. }
  51. void Bullet::destroyPixels(int& k, int x, int y)
  52. {
  53. int plus = 1;
  54. int dir = 0;
  55. int curr = 0;
  56. bool q[4] = {false, false, false, false};
  57. while(k <= 6400) {
  58. if(_foreground->destroy(x, y))
  59. {
  60. q[dir] = true;
  61. ++k;
  62. }
  63. switch(dir)
  64. {
  65. case 0: ++x; break;
  66. case 1: ++y; break;
  67. case 2: --x; break;
  68. case 3: --y; break;
  69. default: break;
  70. }
  71. ++curr;
  72. if(curr >= plus)
  73. {
  74. curr = 0;
  75. ++dir;
  76. if(dir == 4)
  77. {
  78. dir = 0;
  79. /*
  80. * This prevents destroying remote islands of foreground.
  81. */
  82. bool exit = true;
  83. for(int i = 0; i < 4; ++i)
  84. {
  85. if(q[i])
  86. exit = false;
  87. q[i] = false;
  88. }
  89. if(exit)
  90. break;
  91. }
  92. if(dir == 0 or dir == 2)
  93. ++plus;
  94. }
  95. }
  96. }
  97. void Bullet::update(sf::Time delta)
  98. {
  99. float seconds = delta.asSeconds();
  100. const double degree = 3.14159265358 / 180.;
  101. sf::Vector2f movement;
  102. movement.x = std::sin(getRotation() * degree) * 1080.f * seconds;
  103. movement.y = -std::cos(getRotation() * degree) * 1080.f * seconds;
  104. move(movement);
  105. Collidable::updateTransform(getTransform());
  106. if(!_hit)
  107. {
  108. int k = pixelPerfect(*_foreground);
  109. if(k != -1)
  110. {
  111. sf::Vector2i vec = (sf::Vector2i)getTransform().transformPoint(_cmap[k]);
  112. int n = vec.x, m = vec.y;
  113. int k = 0;
  114. destroyPixels(k, n, m);
  115. _foreground->reloadFromPixel(vec.x, vec.y, true);
  116. _explosion.play();
  117. _hit = true;
  118. }
  119. }
  120. if(_hit and _sound.getStatus() == sf::Sound::Status::Stopped and _explosion.getStatus() == sf::Sound::Status::Stopped)
  121. {
  122. _dead = true;
  123. }
  124. }
  125. const bool Bullet::isDead() const
  126. {
  127. return _dead;
  128. }