#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 sparksSat[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;
}
}

void reg(byte id) {
lightersPos[0][id] = gPos[0];
lightersPos[1][id] = gPos[1];
sparksSat[id] = 10;
sparksColor[id] = random();
}

void phisics(byte id) {
// lcolor[id] = random();
sparksSat[id] += (255. / (float)WIDTH);
else
}
if (lightersPos[0][id] <= 0 || lightersPos[0][id] >= (WIDTH-1) * 10 || lightersPos[1][id] < 0) {
reg(id);
}
}

void draw() {
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;
}
//FastLED.clear();
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.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);
}
}