-
Notifications
You must be signed in to change notification settings - Fork 0
/
particle_factories.py
127 lines (95 loc) · 3.7 KB
/
particle_factories.py
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
from config import *
import utils
import gameObjects
import threading
import factory
import particles
import AI
class GravityArc(AI.Basic):
# def __init__(self, *args):
# super().__init__(*args)
def get_action(self, elapsed_time):
""" get direction from heading and project velocity in that direction
"""
dv = 0.8 * self.parent.velocity / elapsed_time
dv[1] += 9.81 / 40.0 # integrate "half" gravity due to perspective
out = {'dv': dv}
cbs = []
return out, cbs
class ExplosionParticle(particles.ParticleObj):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.nb_updates = self.duration / self.update_rate
self.size_delta_w = self.width / (self.nb_updates * 5)
self.size_delta_h = self.height / (self.nb_updates * 5)
self.rgb = (255, 0, 0)
self.AI = GravityArc(self)
def update(self, seconds):
super().update(seconds)
# update size
self.width -= self.size_delta_w
self.height -= self.size_delta_h
class ExplosionFactory(factory.ParticleObjFactory):
""" at the origin, generate many explosion particles in different directions and sizes """
def __init__(self, **kwargs):
super().__init__()
self.creator = ExplosionParticle
# params
self.nb_particles = 7
self.nb_stored_particles = 10 * self.nb_particles
self.min_particle_size = 0.15 # tiles
self.max_particle_size = 0.4 # tiles
# values
self.values['max_velocity'] = 0.125
self.values['duration'] = 0.75
self.values['objectType'] = "Explosion"
self.values['collideable'] = False
def init_emitter(self):
# create many explosion particles and store until use
self.pool = itertools.cycle([])
for i in range(self.nb_stored_particles):
# random angle, speed, and size
a, b = 0, 2.0 * np.pi
heading = (b - a) * np.random.random() + a
a, b = self.min_particle_size, self.max_particle_size
size = (b - a) * np.random.random() + a
a, b = 0.5 * self.values['max_velocity'], self.values['max_velocity']
velocity = (b - a) * np.random.random() + a
direction = (m2d.Orientation(heading) * m2d.Vector.e0).array
dx_actual, dy_actual = velocity * direction
obj = super().create(0, 0, dx_actual = dx_actual, dy_actual = dy_actual, width = size, height = size)
# setup
obj.setSpriteStatus(visible=True)
self.pool.append(obj)
def create_new(self, x, y):
# take non-active particles from the emitter
for i in range(self.nb_particles):
particle = next(self.pool)
xx = x + 0.1 * np.random.random()
yy = y + 0.1 * np.random.random()
# start the threads
[obj.start() for obj in out]
return out
def create(self, x, y):
# create many explosion particles and store until use
out = []
for i in range(self.nb_particles):
# random angle, speed, and size
a, b = 0, 2.0 * np.pi
heading = (b - a) * np.random.random() + a
a, b = self.min_particle_size, self.max_particle_size
size = (b - a) * np.random.random() + a
a, b = 0.5 * self.values['max_velocity'], self.values['max_velocity']
velocity = (b - a) * np.random.random() + a
direction = (m2d.Orientation(heading) * m2d.Vector.e0).array
dx_actual, dy_actual = velocity * direction
xx = x + 0.1 * np.random.random()
yy = y + 0.1 * np.random.random()
obj = super().create(xx, yy, dx_actual = dx_actual, dy_actual = dy_actual, width = size, height = size)
# setup
obj.setSpriteStatus(visible=True)
out.append(obj)
# start the threads
[obj.start() for obj in out]
return out
explosionFactory = ExplosionFactory()