#include "FastLED.h"
// Matrix size
#define WIDTH 32
#define HEIGHT 32
#define NUM_LEDS HEIGHT * WIDTH
#define MATRIX_TYPE 1
// LEDs pin
#define DATA_PIN 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS];
#define scale (16)
#define LIGHTERS_AM WIDTH
float lightersPos[2][LIGHTERS_AM];
float lightersSpeed[2][LIGHTERS_AM];
float sparksSat[LIGHTERS_AM];
float sparksFade[LIGHTERS_AM];
byte sparksColor[LIGHTERS_AM];
static byte period = 10;
int gPos[2];
bool run = true;
void drawPixelXYF(float x, float y, CRGB color)
{
// if (x < 0 || y < 0 || x > ((float)WIDTH - 1) || y > ((float)HEIGHT - 1)) return;
uint8_t xx = (x - (int)x) * 255, yy = (y - (int)y) * 255, ix = 255 - xx, iy = 255 - yy;
// calculate the intensities for each affected pixel
#define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8))
uint8_t wu[4] = {WU_WEIGHT(ix, iy), WU_WEIGHT(xx, iy),
WU_WEIGHT(ix, yy), WU_WEIGHT(xx, yy)
};
// multiply the intensities by the colour, and saturating-add them to the pixels
for (uint8_t i = 0; i < 4; i++) {
int16_t xn = x + (i & 1), yn = y + ((i >> 1) & 1);
CRGB clr = leds[XY(xn, yn)];
clr.r = qadd8(clr.r, (color.r * wu[i]) >> 8);
clr.g = qadd8(clr.g, (color.g * wu[i]) >> 8);
clr.b = qadd8(clr.b, (color.b * wu[i]) >> 8);
leds[XY(xn, yn)] = clr;
}
}
bool loadingFlag = true;
void reg(byte id) {
lightersPos[0][id] = gPos[0];
lightersPos[1][id] = gPos[1];
lightersSpeed[0][id] = random(-10, 10);
lightersSpeed[1][id] = random(-5, 20);
sparksSat[id] = 10;
sparksFade[id] = 255;
sparksColor[id] = random();
}
void phisics(byte id) {
// lcolor[id] = random();
lightersPos[0][id] += lightersSpeed[0][id];
lightersPos[1][id] += lightersSpeed[1][id];
lightersSpeed[1][id] -= .98;
sparksSat[id] += (255. / (float)WIDTH);
sparksFade[id] -= (255. / (float)(HEIGHT*1.5));
if (lightersSpeed[0][id] < 0 || lightersSpeed[0][id] > 0) {
if (lightersSpeed[0][id] > 0)
lightersSpeed[0][id] -= 0.1;
else
lightersSpeed[0][id] += 0.1;
}
if (lightersPos[0][id] <= 0 || lightersPos[0][id] >= WIDTH * 10 || lightersPos[1][id] < 0) {
reg(id);
}
}
void draw() {
if (loadingFlag) {
for (byte i = 0; i < map(scale, 1, 16, 1, LIGHTERS_AM); i++) {
reg(i);
}
gPos[1] = (HEIGHT / 2) * 10;
gPos[0] = (WIDTH / 2) * 10;
loadingFlag = false;
}
//FastLED.clear();
fadeToBlackBy(leds, NUM_LEDS, beatsin8(5, 20, 100));
if (run) {
gPos[1] = beatsin16(5, 0, HEIGHT * 10);
gPos[0] = beatsin16(6, 0, WIDTH * 10);
}else{
gPos[1] = (HEIGHT / 2) * 10;
gPos[0] = (WIDTH / 2) * 10;
}
for (byte i = 0; i < map(scale, 1, 16, 1, LIGHTERS_AM); i++) {
phisics(i);
if (lightersPos[1][i] < ((HEIGHT - 1) * 10))
if (lightersPos[0][i] < ((WIDTH - 1) * 10) and lightersPos[0][i] >= 0)
drawPixelXYF(lightersPos[0][i] / 10, (lightersPos[1][i] / 10), CHSV(sparksColor[i], constrain(sparksSat[i], 5, 255), constrain(sparksFade[i], 32, 255)));
}
EVERY_N_SECONDS(period) {
for (byte i = 0; i < LIGHTERS_AM; i++)reg(i);
period = random(10, 60);
}
}
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
draw();
FastLED.show();
} //loop
uint16_t XY (uint8_t x, uint8_t y) {
if ((y % 2 == 0) || MATRIX_TYPE) // если чётная строка
{
return ((uint32_t)y * WIDTH + x) % (WIDTH * HEIGHT);
}
else // если нечётная строка
{
return ((uint32_t)y * WIDTH + WIDTH - x - 1) % (WIDTH * HEIGHT);
}
}