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 #ifndef HEADER_SUPERTUX_OBJECT_PARTICLESYSTEM_HPP
18 #define HEADER_SUPERTUX_OBJECT_PARTICLESYSTEM_HPP
19 
20 #include <vector>
21 
22 #include "math/vector.hpp"
23 #include "squirrel/exposed_object.hpp"
24 #include "scripting/particlesystem.hpp"
25 #include "supertux/game_object.hpp"
26 #include "video/surface_ptr.hpp"
27 
28 class ReaderMapping;
29 
30 /**
31   This is the base class for particle systems. It is responsible for
32   storing a set of particles with each having an x- and y-coordinate
33   the number of the layer where it should be drawn and a texture.
34 
35   The coordinate system used here is a virtual one. It would be a bad
36   idea to populate whole levels with particles. So we're using a
37   virtual rectangle here that is tiled onto the level when drawing.
38   This rect.has the size (virtual_width, virtual_height). We're using
39   modulo on the particle coordinates, so when a particle leaves left,
40   it'll reenter at the right side.
41 
42   Classes that implement a particle system should subclass from this
43   class, initialize particles in the constructor and move them in the
44   simulate function.
45  */
46 class ParticleSystem : public GameObject,
47                        public ExposedObject<ParticleSystem, scripting::ParticleSystem>
48 {
49 public:
50   ParticleSystem(const ReaderMapping& reader, float max_particle_size = 60);
51   ParticleSystem(float max_particle_size = 60);
52   ~ParticleSystem() override;
53 
54   virtual void draw(DrawingContext& context) override;
55 
get_class() const56   virtual std::string get_class() const override { return "particle-system"; }
get_display_name() const57   virtual std::string get_display_name() const override { return _("Particle system"); }
58   virtual ObjectSettings get_settings() override;
59 
60   void set_enabled(bool enabled_);
61   bool get_enabled() const;
62 
get_layer() const63   int get_layer() const { return z_pos; }
64 
65 protected:
66   class Particle
67   {
68   public:
Particle()69     Particle() :
70       pos(0.0f, 0.0f),
71       angle(),
72       texture(),
73       alpha(),
74       scale(1.f) // This currently only works in the custom particle system
75     {}
76 
~Particle()77     virtual ~Particle()
78     {}
79 
80     Vector pos;
81     // angle at which to draw particle
82     float angle;
83     SurfacePtr texture;
84     float alpha;
85     float scale; // see initializer
86 
87   private:
88     Particle(const Particle&) = delete;
89     Particle& operator=(const Particle&) = delete;
90   };
91 
92 protected:
93   float max_particle_size;
94   int z_pos;
95   std::vector<std::unique_ptr<Particle> > particles;
96   float virtual_width;
97   float virtual_height;
98   bool enabled;
99 
100 private:
101   ParticleSystem(const ParticleSystem&) = delete;
102   ParticleSystem& operator=(const ParticleSystem&) = delete;
103 };
104 
105 #endif
106 
107 /* EOF */
108