particles.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // SuperTux
  2. // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  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. #include "object/particles.hpp"
  17. #include <math.h>
  18. #include "math/random.hpp"
  19. #include "math/util.hpp"
  20. #include "object/camera.hpp"
  21. #include "supertux/sector.hpp"
  22. #include "video/drawing_context.hpp"
  23. #include "video/video_system.hpp"
  24. #include "video/viewport.hpp"
  25. //TODO: remove this function in favor of the one below
  26. Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
  27. const Vector& initial_velocity, const Vector& acceleration, int number,
  28. Color color_, int size_, float life_time, int drawing_layer_) :
  29. accel(acceleration),
  30. timer(),
  31. live_forever(),
  32. color(color_),
  33. size(static_cast<float>(size_)),
  34. drawing_layer(drawing_layer_),
  35. particles()
  36. {
  37. if (life_time == 0) {
  38. live_forever = true;
  39. } else {
  40. live_forever = false;
  41. timer.start(life_time);
  42. }
  43. // create particles
  44. for (int p = 0; p < number; p++)
  45. {
  46. auto particle = std::make_unique<Particle>();
  47. particle->pos = epicenter;
  48. float angle = math::radians(graphicsRandom.randf(static_cast<float>(min_angle), static_cast<float>(max_angle)));
  49. particle->vel.x = /*fabs*/(sinf(angle)) * initial_velocity.x;
  50. // if(angle >= math::PI && angle < math::TAU)
  51. // particle->vel.x *= -1; // work around to fix signal
  52. particle->vel.y = /*fabs*/(cosf(angle)) * initial_velocity.y;
  53. // if(angle >= math::PI_2 && angle < 3*math::PI_2)
  54. // particle->vel.y *= -1;
  55. particles.push_back(std::move(particle));
  56. }
  57. }
  58. Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
  59. const float min_initial_velocity, const float max_initial_velocity,
  60. const Vector& acceleration, int number, Color color_,
  61. int size_, float life_time, int drawing_layer_) :
  62. accel(acceleration),
  63. timer(),
  64. live_forever(),
  65. color(color_),
  66. size(static_cast<float>(size_)),
  67. drawing_layer(drawing_layer_),
  68. particles()
  69. {
  70. if (life_time == 0) {
  71. live_forever = true;
  72. } else {
  73. live_forever = false;
  74. timer.start(life_time);
  75. }
  76. // create particles
  77. for (int p = 0; p < number; p++)
  78. {
  79. auto particle = std::make_unique<Particle>();
  80. particle->pos = epicenter;
  81. float velocity = (min_initial_velocity == max_initial_velocity) ? min_initial_velocity :
  82. graphicsRandom.randf(min_initial_velocity, max_initial_velocity);
  83. float angle = (min_angle == max_angle) ?
  84. math::radians(static_cast<float>(min_angle)) :
  85. math::radians(graphicsRandom.randf(static_cast<float>(min_angle), static_cast<float>(max_angle)));
  86. // Note that angle defined as clockwise from vertical (up is zero degrees, right is 90 degrees)
  87. particle->vel.x = (sinf(angle)) * velocity;
  88. particle->vel.y = (-cosf(angle)) * velocity;
  89. particles.push_back(std::move(particle));
  90. }
  91. }
  92. void
  93. Particles::update(float dt_sec)
  94. {
  95. Camera& camera = Sector::get().get_camera();
  96. // update particles
  97. for (auto i = particles.begin(); i != particles.end(); ) {
  98. (*i)->pos.x += (*i)->vel.x * dt_sec;
  99. (*i)->pos.y += (*i)->vel.y * dt_sec;
  100. (*i)->vel.x += accel.x * dt_sec;
  101. (*i)->vel.y += accel.y * dt_sec;
  102. if (!camera.get_rect().contains((*i)->pos)) {
  103. i = particles.erase(i);
  104. } else {
  105. ++i;
  106. }
  107. }
  108. if ((timer.check() && !live_forever) || particles.size() == 0)
  109. remove_me();
  110. }
  111. void
  112. Particles::draw(DrawingContext& context)
  113. {
  114. // draw particles
  115. for (auto& particle : particles) {
  116. context.color().draw_filled_rect(Rectf(particle->pos, Sizef(size,size)), color, drawing_layer);
  117. }
  118. }
  119. /* EOF */