Brought back particles for bomb explosions
[supertux.git] / src / object / particles.cpp
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
17 #include "object/particles.hpp"
18
19 #include <math.h>
20
21 #include "math/random_generator.hpp"
22 #include "object/camera.hpp"
23 #include "supertux/globals.hpp"
24 #include "supertux/sector.hpp"
25 #include "video/drawing_context.hpp"
26
27 //TODO: remove this function in favor of the one below
28 Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
29                      const Vector& initial_velocity, const Vector& acceleration, int number,
30                      Color color_, int size_, float life_time, int drawing_layer_) :
31   accel(acceleration),
32   timer(),
33   live_forever(),
34   color(color_),
35   size(size_),
36   drawing_layer(drawing_layer_),
37   particles()
38 {
39   if(life_time == 0) {
40     live_forever = true;
41   } else {
42     live_forever = false;
43     timer.start(life_time);
44   }
45
46   // create particles
47   for(int p = 0; p < number; p++)
48   {
49     Particle* particle = new Particle;
50     particle->pos = epicenter;
51
52     float angle = graphicsRandom.rand(min_angle, max_angle)
53       * (M_PI / 180);  // convert to radius (radians?)
54     particle->vel.x = /*fabs*/(sin(angle)) * initial_velocity.x;
55     //    if(angle >= M_PI && angle < M_PI*2)
56     //      particle->vel.x *= -1;  // work around to fix signal
57     particle->vel.y = /*fabs*/(cos(angle)) * initial_velocity.y;
58     //    if(angle >= M_PI_2 && angle < 3*M_PI_2)
59     //      particle->vel.y *= -1;
60
61     particles.push_back(particle);
62   }
63 }
64
65 Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
66                      const float min_initial_velocity, const float max_initial_velocity,
67                      const Vector& acceleration, int number, Color color_,
68                      int size_, float life_time, int drawing_layer_) :
69
70   accel(acceleration),
71   timer(),
72   live_forever(),
73   color(color_),
74   size(size_),
75   drawing_layer(drawing_layer_),
76   particles()
77 {
78   if(life_time == 0) {
79     live_forever = true;
80   } else {
81     live_forever = false;
82     timer.start(life_time);
83   }
84
85   // create particles
86   for(int p = 0; p < number; p++)
87   {
88     Particle* particle = new Particle;
89     particle->pos = epicenter;
90
91     float velocity = graphicsRandom.rand(min_initial_velocity, max_initial_velocity);
92     float angle = graphicsRandom.rand(min_angle, max_angle) * (M_PI / 180);  // convert to radians
93     particle->vel.x = (cos(angle)) * velocity;
94     particle->vel.y = (-sin(angle)) * velocity;
95
96     particles.push_back(particle);
97   }
98 }
99
100 Particles::~Particles()
101 {
102   // free particles
103   for(std::vector<Particle*>::iterator i = particles.begin();
104       i < particles.end(); ++i)
105     delete (*i);
106 }
107
108 void
109 Particles::update(float elapsed_time)
110 {
111   Vector camera = Sector::current()->camera->get_translation();
112
113   // update particles
114   for(std::vector<Particle*>::iterator i = particles.begin();
115       i != particles.end(); ) {
116     (*i)->pos.x += (*i)->vel.x * elapsed_time;
117     (*i)->pos.y += (*i)->vel.y * elapsed_time;
118
119     (*i)->vel.x += accel.x * elapsed_time;
120     (*i)->vel.y += accel.y * elapsed_time;
121
122     if((*i)->pos.x < camera.x || (*i)->pos.x > SCREEN_WIDTH + camera.x ||
123        (*i)->pos.y < camera.y || (*i)->pos.y > SCREEN_HEIGHT + camera.y) {
124       delete (*i);
125       i = particles.erase(i);
126     } else {
127       ++i;
128     }
129   }
130
131   if((timer.check() && !live_forever) || particles.size() == 0)
132     remove_me();
133 }
134
135 void
136 Particles::draw(DrawingContext& context)
137 {
138   // draw particles
139   for(std::vector<Particle*>::iterator i = particles.begin();
140       i != particles.end(); ++i) {
141     context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer);
142   }
143 }
144
145 /* EOF */