#include "FastLED.h"
// Matrix size
#define NUM_ROWS 32
#define NUM_COLS 32
#define WIDTH NUM_COLS
#define HEIGHT NUM_ROWS
#define NUM_LEDS NUM_ROWS * NUM_COLS
#define MATRIX_TYPE 1
// LEDs pin
#define DATA_PIN 6
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS + 1];
#define SPARKS_AM 4
float SpeedK = 1;
float SpeedDecX = .01;
float SpeedDecY = 0;
#define Board 1
struct {
bool GravityX, GravityY;
int16_t genPosX, genPosY;
int16_t gravityPosX, gravityPosY;
void setGenPos(int16_t x, int16_t y) {
genPosX = x;
genPosY = y;
}
void setGravityPos(int16_t x, int16_t y) {
GravityX = 1; GravityY = 1;
gravityPosX = x;
gravityPosY = y;
}
void setGravityPos(int16_t x, bool y) {
if (y) {
gravityPosX = x;
GravityX = 1; GravityY = 0;
}
else {
gravityPosY = y;
GravityX = 0; GravityY = 1;
}
}
} PS_Var;
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 wu_pixel(uint32_t x, uint32_t y, CRGB * col) { //awesome wu_pixel procedure by reddit u/sutaburosu
// extract the fractional parts and derive their inverses
uint8_t xx = x & 0xff, yy = y & 0xff, 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++) {
uint16_t xy = XY((x >> 8) + (i & 1), (y >> 8) + ((i >> 1) & 1));
leds[xy].r = qadd8(leds[xy].r, col -> r * wu[i] >> 8);
leds[xy].g = qadd8(leds[xy].g, col -> g * wu[i] >> 8);
leds[xy].b = qadd8(leds[xy].b, col -> b * wu[i] >> 8);
}
}
bool loadingFlag = true;
struct {
int16_t PosX, PosY;
float SpeedX, SpeedY;
uint8_t Fade;
byte Color;
void reg() {
SpeedY = random(0, 10);
if (PosY < 10) {
PosY = HEIGHT * 10;
SpeedY = 0;
}
SpeedX = ((random()%2) * 2) * random(0,10);
Fade = 255;
Color = random(0, 70);
}
void boom() {
int maxX = pow(WIDTH / 6, 2), maxY = pow(HEIGHT / 6, 2);
for(uint8_t i = 0; i < 3; i++){
int xoffset = (i)?random(0,WIDTH / 6)*(((random()%2) * 2) - 1):0;
int yoffset = (i)?random(0,HEIGHT / 6)*(((random()%2) * 2) - 1):0;
//Serial.println(String(xoffset)+ " " + String(yoffset) + " ");
for (int8_t x = -(WIDTH /4); x < WIDTH / 4; x++) {
for (int8_t y = -(HEIGHT / 4); y < HEIGHT / 4; y++) {
CRGB boomcol = CHSV(50, 120, constrain(map((x * x + y * y), 0, maxX + maxY, 255, 0), 0, 255));
leds[XY(xoffset + PosX / 10 + x, yoffset + PosY / 10 + y)] += boomcol;
}}
}
}
void phisics() {
if (SpeedK) {
if (PS_Var.GravityX) {
if (PS_Var.gravityPosX < PosX)
SpeedX -= SpeedK;
else
SpeedX += SpeedK;
}
if (PS_Var.GravityY) {
if (PS_Var.gravityPosY < PosY)
SpeedY -= SpeedK;
else
SpeedY += SpeedK;
}
}
if (SpeedDecX || SpeedX) {
if (SpeedX > 0)
SpeedX -= SpeedDecX;
else
SpeedX += SpeedDecX;
if (abs(SpeedX) <= SpeedDecX)
SpeedX = 0;
}
if (SpeedDecY || SpeedY) {
if (SpeedY > 0)
SpeedY -= SpeedDecY;
else
SpeedY += SpeedDecY;
if (abs(SpeedY) <= SpeedDecY)
SpeedX = 0;
}
if (Board) {
if (PosX < 0 || PosX >= WIDTH * 10) SpeedX = -SpeedX;
}
if (PosY < 0) {
SpeedY = -SpeedY;
}
PosX += /*constrain(*/SpeedX/*, -10, 10)*/;
PosY += /*constrain(*/SpeedY/*, -10, 10)*/;
Fade -= 4;
if ((SpeedY > 0 && SpeedY < 1 && PosY < 20) || Fade <= 32) {
if(PosY > 10)boom();
reg();
}
}
void render(CRGB Col) {
phisics();
if (PosX < ((HEIGHT - 1) * 10) && PosY >= 0)
if (PosX < ((WIDTH - 1) * 10) && PosX >= 0) {
CRGB color = Col;
wu_pixel(PosX * 25.6, PosY * 25.6, & color);
}
}
} dot[SPARKS_AM];
void draw() {
if (loadingFlag) {
PS_Var.setGravityPos(0, false);
for (byte i = 0; i < SPARKS_AM; i++) {
dot[i].reg();
dot[i].PosY = HEIGHT * 5;
dot[i].PosX = random(0, WIDTH * 10);
dot[i].Fade = random();
}
loadingFlag = false;
}
fadeToBlackBy(leds, NUM_LEDS, 32);
//FastLED.clear();
for (byte i = 0; i < SPARKS_AM; i++) {
dot[i].render(CHSV(dot[i].Color, 255, 255));
}
delay(16);
}
void setup() {
//Serial.begin(250000);
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 (x >= WIDTH || y >= HEIGHT) return NUM_LEDS;
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);
}
}