forked from mrcodetastic/ESP32-HUB75-MatrixPanel-DMA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPatternFireworks.hpp
235 lines (188 loc) · 6.27 KB
/
PatternFireworks.hpp
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
235
#ifndef FireWork_H
#define FireWork_H
/****************************************************************
* Fireworks Class
****************************************************************/
// Ripped from: https://github.com/lmirel/MorphingClockRemix
const int FIREWORKS = 4; // Number of fireworks
const int FIREWORK_PARTICLES = 32; // Number of particles per firework
const float GRAVITY = 0.03f;
const float baselineSpeed = -1.2f;
const float maxSpeed = -2.0f;
class Firework
{
public:
float x[FIREWORK_PARTICLES];
float y[FIREWORK_PARTICLES];
char lx[FIREWORK_PARTICLES], ly[FIREWORK_PARTICLES];
float xSpeed[FIREWORK_PARTICLES];
float ySpeed[FIREWORK_PARTICLES];
char red;
char blue;
char green;
char alpha;
int framesUntilLaunch;
char particleSize;
bool hasExploded;
Firework(); // Constructor declaration
void initialise();
void move();
void explode();
};
// Constructor implementation
Firework::Firework()
{
initialise();
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
{
lx[loop] = 0;
ly[loop] = VPANEL_H + 1; // Push the particle location down off the bottom of the screen
}
}
void Firework::initialise()
{
// Pick an initial x location and random x/y speeds
float xLoc = (rand() % VPANEL_W);
float xSpeedVal = baselineSpeed + (rand() % (int)maxSpeed);
float ySpeedVal = baselineSpeed + (rand() % (int)maxSpeed);
// Set initial x/y location and speeds
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
{
x[loop] = xLoc;
y[loop] = VPANEL_H + 1; // Push the particle location down off the bottom of the screen
xSpeed[loop] = xSpeedVal;
ySpeed[loop] = ySpeedVal;
//don't reset these otherwise particles won't be removed
//lx[loop] = 0;
//ly[loop] = LAYER_HEIGHT + 1; // Push the particle location down off the bottom of the screen
}
// Assign a random colour and full alpha (i.e. particle is completely opaque)
red = (rand() % 255);/// (float)RAND_MAX);
green = (rand() % 255); /// (float)RAND_MAX);
blue = (rand() % 255); /// (float)RAND_MAX);
alpha = 50;//max particle frames
// Firework will launch after a random amount of frames between 0 and 400
framesUntilLaunch = ((int)rand() % (VPANEL_H));
// Size of the particle (as thrown to glPointSize) - range is 1.0f to 4.0f
particleSize = 1.0f + ((float)rand() / (float)RAND_MAX) * 3.0f;
// Flag to keep trackof whether the firework has exploded or not
hasExploded = false;
//cout << "Initialised a firework." << endl;
}
void Firework::move()
{
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
{
// Once the firework is ready to launch start moving the particles
if (framesUntilLaunch <= 0)
{
//draw black on last known position
//tl->drawPixel (x[loop], y[loop], cc_blk);
lx[loop] = x[loop];
ly[loop] = y[loop];
//
x[loop] += xSpeed[loop];
y[loop] += ySpeed[loop];
ySpeed[loop] += GRAVITY;
}
}
framesUntilLaunch--;
// Once a fireworks speed turns positive (i.e. at top of arc) - blow it up!
if (ySpeed[0] > 0.0f)
{
for (int loop2 = 0; loop2 < FIREWORK_PARTICLES; loop2++)
{
// Set a random x and y speed beteen -4 and + 4
xSpeed[loop2] = -2 + (rand() / (float)RAND_MAX) * 4;
ySpeed[loop2] = -2 + (rand() / (float)RAND_MAX) * 4;
}
//cout << "Boom!" << endl;
hasExploded = true;
}
}
void Firework::explode()
{
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
{
// Dampen the horizontal speed by 1% per frame
xSpeed[loop] *= 0.99;
//draw black on last known position (NO LONGER USED tl->dim used instead)
//tl->drawPixel (x[loop], y[loop], cc_blk);
lx[loop] = x[loop];
ly[loop] = y[loop];
//
// Move the particle
x[loop] += xSpeed[loop];
y[loop] += ySpeed[loop];
// Apply gravity to the particle's speed
ySpeed[loop] += GRAVITY;
}
// Fade out the particles (alpha is stored per firework, not per particle)
if (alpha > 0)
{
alpha -= 1;
}
else // Once the alpha hits zero reset the firework
{
initialise();
}
}
/*********************** */
class PatternFirework : public Drawable {
public:
PatternFirework() {
name = (char *)"PatternFirework";
}
void start();
unsigned int drawFrame();
void stop();
private:
// Create our array of fireworks
Firework fw[FIREWORKS];
};
void PatternFirework::start() { }
void PatternFirework::stop() { }
unsigned int PatternFirework::drawFrame()
{
effects.DimAll(250);
CRGB cc_frw;
//display.fillScreen (0);
// Draw fireworks
//cout << "Firework count is: " << Firework::fireworkCount << endl;
for (int loop = 0; loop < FIREWORKS; loop++)
{
for (int particleLoop = 0; particleLoop < FIREWORK_PARTICLES; particleLoop++)
{
// Set colour to yellow on way up, then whatever colour firework should be when exploded
if (fw[loop].hasExploded == false)
{
//glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
cc_frw = CRGB (255, 255, 0);
}
else
{
//glColor4f(fw[loop].red, fw[loop].green, fw[loop].blue, fw[loop].alpha);
//glVertex2f(fw[loop].x[particleLoop], fw[loop].y[particleLoop]);
cc_frw = CRGB (fw[loop].red, fw[loop].green, fw[loop].blue);
}
// Draw the point
//glVertex2f(fw[loop].x[particleLoop], fw[loop].y[particleLoop]);
effects.setPixel (fw[loop].x[particleLoop], fw[loop].y[particleLoop], cc_frw);
// effects.setPixel (fw[loop].lx[particleLoop], fw[loop].ly[particleLoop], 0);
}
// Move the firework appropriately depending on its explosion state
if (fw[loop].hasExploded == false)
{
fw[loop].move();
}
else
{
fw[loop].explode();
}
//
//delay (10);
} // end loop
effects.ShowFrame();
return 20;
} // end drawframe
#endif