forked from hiulit/Godot-3-2D-Fake-Explosion-Particles
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fake_explosion_particles.gd
234 lines (174 loc) · 6.21 KB
/
fake_explosion_particles.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
extends Node2D
@export var min_particles_number: int = 200
@export var max_particles_number: int = 400
@export var min_particles_gravity: float = 200.0
@export var max_particles_gravity: float = 600.0
@export var min_particles_velocity: float = 200.0
@export var max_particles_velocity: float = 600.0
@export var max_particles_position_x: int = ProjectSettings.get_setting("display/window/size/viewport_width")
@export var max_particles_position_y: int = ProjectSettings.get_setting("display/window/size/viewport_height")
@export var min_particles_size: int = 1
@export var max_particles_size: int = 3
@export var get_random_position: bool = false
@export var start_timer: bool = false
@export var timer_wait_time: float = 1.0
@export var particles_explode: bool = false
@export var group_name: String = "fake_explosion_particles"
var particles = []
var particles_number
var particles_initial_position
var particles_colors_with_weights = [
[4, Color("#ffffff")],
[2, Color("#000000")],
[8, Color("#ff004d")],
[8, Color("#ffa300")],
[10, Color("#ffec27")]
]
var particles_timer
func _ready():
# Add to a group so it can be found from anywhere.
add_to_group(group_name)
# Create the initial particles.
_create_particles()
# Create a timer.
particles_timer = Timer.new()
particles_timer.one_shot = false
particles_timer.wait_time = timer_wait_time
particles_timer.set_timer_process_callback(1)
particles_timer.connect("timeout", Callable(self, "_on_particles_timer_timeout"))
add_child(particles_timer, true)
if start_timer: particles_timer.start()
func _process(delta):
# If there are particles in the particles array and
# 'particles_explode' is 'true', make them explode.
if particles.size() > 0 and particles_explode == true:
_particles_explode(delta)
# Redraw the particles every frame.
queue_redraw()
# If there are no particles in the particles array, free the node.
if particles.size() == 0 and not start_timer:
queue_free()
func _draw():
for particle in particles:
# Draw the particles.
draw_rect(Rect2(particle.position, particle.size), particle.color)
func _particles_explode(delta):
for particle in particles:
particle.velocity.x *= particle.velocity_increment.x
particle.velocity.y *= particle.velocity_increment.y
particle.position += (particle.velocity + particle.gravity) * delta
particle.time += delta
if particle.time > _get_random_time():
# Fade out the particles.
if particle.color.a > 0:
particle.color.a -= particle.alpha * delta
if particle.color.a < 0:
particle.color.a = 0
# If the particle is invisible...
if particle.color.a == 0:
# ... if there are particles in the particles array...
if particles.size() > 0:
# ... find the particle in the particles array...
var i = particles.find(particle)
# ... and remove it from the particles array.
particles.remove_at(i)
func _create_particles():
# Set the node's position to (0,0) to get proper random position values.
if get_random_position: position = Vector2.ZERO
# Set initial values.
particles_initial_position = _get_random_position() if get_random_position else Vector2.ZERO
particles_number = _get_random_number()
# Empty the particles array.
particles.clear()
for i in particles_number:
# Create the particle object.
var particle = {
alpha = null,
color = null,
gravity = null,
position = particles_initial_position,
size = null,
time = 0,
velocity = null
}
# Assign random variables to the particle object.
particle.alpha = _get_random_alpha()
particle.color = _get_random_color()
particle.gravity = _get_random_gravity()
particle.size = _get_random_size()
particle.velocity = _get_random_velocity()
particle.velocity_increment = _get_random_velocity_increment()
# Push the particle to the particles array.
particles.push_back(particle)
func _get_random_alpha():
randomize()
var random_alpha = randf_range(2, 10)
return random_alpha
func _get_random_color():
randomize()
var random_color = _rand_array(particles_colors_with_weights)
return random_color
func _get_random_gravity():
randomize()
var random_gravity = Vector2(
randf_range(
-randf_range(min_particles_gravity, max_particles_gravity),
randf_range(min_particles_gravity, max_particles_gravity)
),
randf_range(
randf_range(min_particles_gravity * 2, max_particles_gravity * 2),
randf_range(min_particles_gravity * 2, max_particles_gravity * 2)
)
)
return random_gravity
func _get_random_number():
randomize()
var random_number = round(randf_range(min_particles_number, max_particles_number))
return random_number
func _get_random_position():
randomize()
var random_position_x = randf_range(0, max_particles_position_x)
var random_position_y = randf_range(0, max_particles_position_y)
var random_position = Vector2(random_position_x, random_position_y)
return random_position
func _get_random_size():
randomize()
var random_size = randi() % max_particles_size + min_particles_size
random_size = Vector2(random_size, random_size)
return random_size
func _get_random_velocity():
randomize()
var random_velocity = Vector2(
randf_range(
-randf_range(min_particles_velocity, max_particles_velocity),
randf_range(min_particles_velocity, max_particles_velocity)
),
randf_range(
-randf_range(min_particles_velocity * 2, max_particles_velocity * 2),
-randf_range(min_particles_velocity * 2, max_particles_velocity * 2)
)
)
return random_velocity
func _get_random_velocity_increment():
randomize()
var random_velocity_increment = Vector2(randf_range(0.991, 1.009), randf_range(0.991, 1.009))
return random_velocity_increment
func _get_random_time():
randomize()
var random_time = randf_range(0.05, 0.1)
return random_time
func _rand_array(array):
# Code from @CowThing (https://pastebin.com/HhdBuUzT).
# Arrays must be [weight, value].
var sum_of_weights = 0
for t in array:
sum_of_weights += t[0]
var x = randf() * sum_of_weights
var cumulative_weight = 0
for t in array:
cumulative_weight += t[0]
if x < cumulative_weight:
return t[1]
func _on_particles_timer_timeout():
# Create new particles every time the timer times out.
_create_particles()