Rewrote effect firework. Now it kinda works.
This commit is contained in:
parent
6ba2854a8d
commit
711719921a
@ -1,7 +1,61 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "prototypes.h"
|
||||||
|
#include "functions.h"
|
||||||
#include "Effect.h"
|
#include "Effect.h"
|
||||||
|
|
||||||
class FireworkEffect : public Effect {
|
enum FireworkDotType { FIREWORK_DOT_NONE, FIREWORK_DOT_SHELL, FIREWORK_DOT_SPARK };
|
||||||
void loop();
|
|
||||||
|
#define EFFECT_FIREWORK_DRAG 255
|
||||||
|
#define EFFECT_FIREWORK_BOUNCE 200
|
||||||
|
#define EFFECT_FIREWORK_GRAVITY 10
|
||||||
|
#define EFFECT_FIREWORK_SPARKS 12
|
||||||
|
|
||||||
|
class FireworkEffect;
|
||||||
|
|
||||||
|
class FireworkEffectDot {
|
||||||
|
private:
|
||||||
|
Window* _window;
|
||||||
|
FireworkEffect* _main;
|
||||||
|
accum88 _x;
|
||||||
|
accum88 _y;
|
||||||
|
saccum78 _xv;
|
||||||
|
saccum78 _yv;
|
||||||
|
accum88 _r;
|
||||||
|
CRGB _color;
|
||||||
|
|
||||||
|
void _screenscale(accum88 a, byte n, byte& screen, byte& screenerr);
|
||||||
|
int16_t _scale15by8_local(int16_t i, fract8 scale);
|
||||||
|
public:
|
||||||
|
byte show;
|
||||||
|
FireworkDotType type;
|
||||||
|
|
||||||
|
FireworkEffectDot(Window* w, FireworkEffect* e);
|
||||||
|
void draw();
|
||||||
|
void move();
|
||||||
|
void ground_launch();
|
||||||
|
void sky_burst(accum88 basex, accum88 basey, saccum78 basedv, CRGB& basecolor);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FireworkEffect : public Effect {
|
||||||
|
private:
|
||||||
|
Window* window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
|
||||||
|
bool _skyburst = 0;
|
||||||
|
|
||||||
|
accum88 _burst_x;
|
||||||
|
accum88 _burst_y;
|
||||||
|
saccum78 _burst_xv;
|
||||||
|
saccum78 _burst_yv;
|
||||||
|
CRGB _burst_color;
|
||||||
|
|
||||||
|
FireworkEffectDot* _dot;
|
||||||
|
FireworkEffectDot* _sparks[EFFECT_FIREWORK_SPARKS];
|
||||||
|
public:
|
||||||
|
FireworkEffect();
|
||||||
|
~FireworkEffect();
|
||||||
|
void skyburst(accum88 x, accum88 y, saccum78 xv, saccum78 yv, CRGB c);
|
||||||
|
boolean supports_window = true;
|
||||||
|
boolean can_be_shown_with_clock();
|
||||||
|
void loop();
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -1,13 +1,183 @@
|
|||||||
|
// Based on https://gist.github.com/kriegsman/68929cbd1d6de4535b20
|
||||||
#include "effect_firework.h"
|
#include "effect_firework.h"
|
||||||
#include "my_fastled.h"
|
|
||||||
#include "functions.h"
|
FireworkEffectDot::FireworkEffectDot(Window* w, FireworkEffect* e) {
|
||||||
#include "config.h"
|
_window = w;
|
||||||
|
_main = e;
|
||||||
|
show = 0;
|
||||||
|
type = FIREWORK_DOT_NONE;
|
||||||
|
_x = 0;
|
||||||
|
_y = 0;
|
||||||
|
_xv = 0;
|
||||||
|
_yv = 0;
|
||||||
|
_r = 0;
|
||||||
|
_color.setRGB(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireworkEffectDot::_screenscale(accum88 a, byte n, byte& screen, byte& screenerr) {
|
||||||
|
byte ia = a >> 8;
|
||||||
|
screen = scale8(ia, n);
|
||||||
|
byte m = screen * (256 / n);
|
||||||
|
screenerr = (ia - m) * scale8(255, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t FireworkEffectDot::_scale15by8_local(int16_t i, fract8 scale) {
|
||||||
|
int16_t result;
|
||||||
|
result = (int32_t)((int32_t) i*scale)/256;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireworkEffectDot::draw() {
|
||||||
|
if (!show) return;
|
||||||
|
byte ix, xe, xc;
|
||||||
|
byte iy, ye, yc;
|
||||||
|
_screenscale(_x, _window->width, ix, xe);
|
||||||
|
_screenscale(_y, _window->height, iy, ye);
|
||||||
|
xc = 255 - xe;
|
||||||
|
yc = 255 - ye;
|
||||||
|
|
||||||
|
CRGB c00 = CRGB(dim8_video( scale8( scale8( _color.r, yc), xc)),
|
||||||
|
dim8_video( scale8( scale8( _color.g, yc), xc)),
|
||||||
|
dim8_video( scale8( scale8( _color.b, yc), xc)));
|
||||||
|
CRGB c01 = CRGB(dim8_video( scale8( scale8( _color.r, ye), xc)),
|
||||||
|
dim8_video( scale8( scale8( _color.g, ye), xc)),
|
||||||
|
dim8_video( scale8( scale8( _color.b, ye), xc)));
|
||||||
|
CRGB c10 = CRGB(dim8_video( scale8( scale8( _color.r, yc), xe)),
|
||||||
|
dim8_video( scale8( scale8( _color.g, yc), xe)),
|
||||||
|
dim8_video( scale8( scale8( _color.b, yc), xe)));
|
||||||
|
CRGB c11 = CRGB(dim8_video( scale8( scale8( _color.r, ye), xe)),
|
||||||
|
dim8_video( scale8( scale8( _color.g, ye), xe)),
|
||||||
|
dim8_video( scale8( scale8( _color.b, ye), xe)));
|
||||||
|
_window->addPixelColor(ix, iy, &c00);
|
||||||
|
_window->addPixelColor(ix, iy+1, &c01);
|
||||||
|
_window->addPixelColor(ix+1, iy, &c10);
|
||||||
|
_window->addPixelColor(ix+1, iy+1, &c11);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireworkEffectDot::move() {
|
||||||
|
if (!show) return;
|
||||||
|
_yv -= EFFECT_FIREWORK_GRAVITY;
|
||||||
|
_xv = _scale15by8_local(_xv, EFFECT_FIREWORK_DRAG);
|
||||||
|
_yv = _scale15by8_local(_yv, EFFECT_FIREWORK_DRAG);
|
||||||
|
|
||||||
|
if (type == FIREWORK_DOT_SPARK) {
|
||||||
|
_xv = _scale15by8_local(_xv, EFFECT_FIREWORK_DRAG);
|
||||||
|
_yv = _scale15by8_local(_yv, EFFECT_FIREWORK_DRAG);
|
||||||
|
_color.nscale8(255);
|
||||||
|
if (!_color) {
|
||||||
|
show = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounce if we hit the ground
|
||||||
|
if (_xv < 0 && _y < (-_yv)) {
|
||||||
|
if (type == FIREWORK_DOT_SPARK) {
|
||||||
|
show = 0;
|
||||||
|
} else {
|
||||||
|
_yv = -_yv;
|
||||||
|
_yv = _scale15by8_local(_yv, EFFECT_FIREWORK_BOUNCE);
|
||||||
|
if (_yv < 500) {
|
||||||
|
show = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_yv < 300) {
|
||||||
|
if (type == FIREWORK_DOT_SHELL) {
|
||||||
|
if (_y > (uint16_t)0x8000) {
|
||||||
|
// boom
|
||||||
|
CRGB white(0xFFFFFF);
|
||||||
|
_window->clear(&white);
|
||||||
|
}
|
||||||
|
show = 0;
|
||||||
|
_main->skyburst(_x, _y, _xv, _yv, _color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == FIREWORK_DOT_SPARK) {
|
||||||
|
if ((_xv > 0 && _x>_xv) || (_xv < 0 && _x<(0xFFFF+_xv))) {
|
||||||
|
_x += _xv;
|
||||||
|
} else {
|
||||||
|
show = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_x += _xv;
|
||||||
|
}
|
||||||
|
_y += _yv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireworkEffectDot::ground_launch() {
|
||||||
|
_xv = (int16_t)random16(600) - (int16_t)300;
|
||||||
|
_yv = 600 + random16(300 + (25 * _window->height));
|
||||||
|
_x = 0x8000;
|
||||||
|
_y = 0;
|
||||||
|
hsv2rgb_rainbow(CHSV(random8(), 240, 200), _color);
|
||||||
|
show = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireworkEffectDot::sky_burst(accum88 basex, accum88 basey, saccum78 basedv, CRGB& basecolor) {
|
||||||
|
_xv = basedv + (int16_t)random16(2000) - (int16_t)1000;
|
||||||
|
_yv = (int16_t)random16(1500) - (int16_t)500;
|
||||||
|
_x = basex;
|
||||||
|
_y = basey;
|
||||||
|
_color = basecolor;
|
||||||
|
_color *= 4;
|
||||||
|
type = FIREWORK_DOT_SPARK;
|
||||||
|
show = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FireworkEffect::skyburst(accum88 x, accum88 y, saccum78 xv, saccum78 yv, CRGB c) {
|
||||||
|
_skyburst = 1;
|
||||||
|
_burst_x = x;
|
||||||
|
_burst_y = y;
|
||||||
|
_burst_xv = xv;
|
||||||
|
_burst_yv = yv;
|
||||||
|
_burst_color = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean FireworkEffect::can_be_shown_with_clock() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void FireworkEffect::loop() {
|
void FireworkEffect::loop() {
|
||||||
blur(EFFECT_FIREWORK_BLUR);
|
window->clear();
|
||||||
fadeToBlackBy(leds, LED_COUNT, EFFECT_FIREWORK_FADEOUT_SPEED);
|
_dot->move();
|
||||||
|
_dot->draw();
|
||||||
if (random8(EFFECT_FIREWORK_SHOT_CHANCE)==0) {
|
for (int i=0; i<EFFECT_FIREWORK_SPARKS; i++) {
|
||||||
leds[random16(LED_COUNT)] = CHSV(random8(), 255, 255);
|
_sparks[i]->move();
|
||||||
|
_sparks[i]->draw();
|
||||||
|
}
|
||||||
|
static uint16_t launch_countdown = 0;
|
||||||
|
if (_dot->show == 0) {
|
||||||
|
if (launch_countdown == 0) {
|
||||||
|
_dot->ground_launch();
|
||||||
|
_dot->type = FIREWORK_DOT_SHELL;
|
||||||
|
launch_countdown = random16(350) + 1;
|
||||||
|
} else {
|
||||||
|
launch_countdown--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_skyburst) {
|
||||||
|
int nsparks = random8(EFFECT_FIREWORK_SPARKS / 2, EFFECT_FIREWORK_SPARKS + 1);
|
||||||
|
for (int i=0; i<nsparks; i++) {
|
||||||
|
_sparks[i]->sky_burst(_burst_x, _burst_y, _burst_yv, _burst_color);
|
||||||
|
_skyburst = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FireworkEffect::FireworkEffect() {
|
||||||
|
_dot = new FireworkEffectDot(window, this);
|
||||||
|
for (int i=0; i<EFFECT_FIREWORK_SPARKS; i++) {
|
||||||
|
_sparks[i] = new FireworkEffectDot(window, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FireworkEffect::~FireworkEffect() {
|
||||||
|
delete window;
|
||||||
|
for (int i=0; i<EFFECT_FIREWORK_SPARKS; i++) {
|
||||||
|
delete _sparks[i];
|
||||||
|
}
|
||||||
|
delete _dot;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user