7 This class provides a number of particle systems:
8 The "type" field should be set to either:
9 point -- emits from a single point in space - requires the "x" and "y" fields to be set
10 rect -- emits particles within a rectangle in space - requires the "rect" field to be set
12 It can operate in two modes, "random" and "ordered".
13 The "method" field should be set to either:
14 random -- randomly generates particles based on parameters -- does nothing with "point"
15 ordered -- generates particles in order from min to max, in a cycle
16 -- for "point" type, this has the effect of making a "spread"
18 Additionally, "ordered" has two modes of operation (does not apply to "point" type):
19 wrap -- will just wrap values when they hit max
20 bounce -- will "bounce" between min and max
25 ParticleSystem
.object
= nil --this must be set to the Object that will be used in the particle system
26 ParticleSystem
.object_args
= nil --the table to pass to the object constructor
27 ParticleSystem
.object_list
= nil --the ObjectList that contains the Objects in the particle system
28 ParticleSystem
.on
= false --whether or not the system is currently emitting
29 ParticleSystem
.type = "point" --the type of particle system
30 ParticleSystem
.method
= "random" --the method in which particles are generated
31 ParticleSystem
.ordered_mode
= "wrap" -- the mode in which ordered will operate
38 ParticleSystem
.rect
= nil
39 ParticleSystem
.ordered_step
= 1
42 ParticleSystem
.particles_per_update_min
= 1 --minimum number of particles to create per call of update
43 ParticleSystem
.particles_per_update_max
= 1 --maximum number of particles to create per call of update
44 ParticleSystem
.update_delay
= 0 -- the delay in calls of update between emittings
45 ParticleSystem
.update_delay_current
= 0 --current count -- do not touch
47 -- The following pertain to the emitted Objects --
49 ParticleSystem
.angle_min
= 0 --minimum angle in degrees
50 ParticleSystem
.angle_max
= 360 --maximum angle in degrees
52 ParticleSystem
.speed_min
= 0 --minimum speed
53 ParticleSystem
.speed_max
= 1 --maximum speed
55 ParticleSystem
.life_min
= 1 --minimum lifetime in updates -- set less than 1 to make infinity
56 ParticleSystem
.life_max
= 1 --maximum lifetime in updates
58 ParticleSystem
.rotation_init_min
= 0 --minimum initial rotation
59 ParticleSystem
.rotation_init_max
= 0 --maximum initial rotation
61 ParticleSystem
.angular_velocity_min
= 0 --minimum angular velocity
62 ParticleSystem
.angular_velocity_max
= 0 --maximum angular velocity
65 ParticleSystem
.ordered_position
= 0
66 ParticleSystem
.ordered_direction
= 1
70 function ParticleSystem
:new(o
)
74 o
.object_list
= ObjectList
:new()
79 --internal function to emit a particle
80 -- recommend: do not use directly
81 function ParticleSystem
:emit(angle
)
82 local tobj
= self
.object
:new(self
.object_args
)
84 --should be random for either creation method, at least for now
85 tobj
.speed
= (math
.random() * (self
.speed_max
- self
.speed_min
)) + self
.speed_min
86 tobj
.rotation
= (math
.random() * (self
.rotation_init_max
- self
.rotation_init_min
)) + self
.rotation_init_min
87 tobj
.angular_velocity
= (math
.random() * (self
.angular_velocity_max
- self
.angular_velocity_min
)) + self
.angular_velocity_min
89 if self
.life_min
< 1 then
92 tobj
.max_updates
= math
.random(self
.life_min
, self
.life_max
)
95 if self
.method
== "random" then
96 tobj
.heading
= math
.random(self
.angle_min
, self
.angle_max
)
98 if self
.type == "point" then
101 elseif self
.type == "rect" then
102 tobj
.x
= math
.random(self
.rect
.x
, self
.rect
.x
+ self
.rect
.w
)
103 tobj
.y
= math
.random(self
.rect
.y
, self
.rect
.y
+ self
.rect
.h
)
105 elseif self
.method
== "ordered" then
106 if self
.type == "point" then
110 elseif self
.type == "rect" then
111 tobj
.angle
= math
.random(self
.angle_min
, self
.angle_max
)
112 tobj
.y
= math
.floor(self
.ordered_position
/ self
.rect
.w
)
113 tobj
.x
= self
.ordered_position
% self
.rect
.w
117 self
.object_list
:push_back(tobj
)
121 --updates all contained Objects and emits more if it is "on"
122 function ParticleSystem
:update(delta
)
123 self
.object_list
:update(delta
)
125 --handles the delay. allows for both frame-based and delta-based animation
126 if self
.update_delay
~= 0 then
128 if self
.update_delay_current
>= self
.update_delay
then
129 self
.update_delay_current
= 0
131 self
.update_delay_current
= self
.update_delay_current
+ delta
134 if self
.update_delay_current
== self
.update_delay
then
135 self
.update_delay_current
= 0
137 self
.update_delay_current
= self
.update_delay_current
+ 1
143 if self
.on
== true and self
.update_delay_current
== 0 then
145 local num_e
= math
.random(self
.particles_per_update_min
, self
.particles_per_update_max
)
147 local angle_spread
= 0
148 if self
.type == "point" and self
.method
== "ordered" then
149 angle_spread
= (self
.angle_max
- self
.angle_min
) / (num_e
)
152 while cur_e
<= num_e
do
153 self
:emit((angle_spread
* (cur_e
- 1)) + self
.angle_min
)
157 if self
.type == "rect" and self
.method
== "ordered" then
158 self
.ordered_position
= self
.ordered_position
+ (self
.ordered_direction
* self
.ordered_step
)
159 if self
.ordered_position
>= self
.rect
.w
* self
.rect
.h
then
160 if self
.ordered_mode
== "wrap" then
161 self
.ordered_position
= 0
162 elseif self
.ordered_mod
== "bounce" then
163 self
.ordered_direction
= -1
165 elseif self
.ordered_position
<= 0 then
166 self
.ordered_direction
= 1
174 --draws all contained Objects
175 function ParticleSystem
:draw()
176 self
.object_list
:draw()