#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 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS + 1];
// Bombs
// remastered(original version is deleted)
// St3P40 aka Stepko
// 17.05.23
#define SPARKS_AM NUM_LEDS / 128
uint8_t SpeedK = 6;
uint8_t SpeedDecX = 1;
uint8_t FadeSpK = 16;
bool Board = 1;
uint16_t limiter = 383;
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;
int16_t Fade;
byte Color;
void reg() {
//SpeedY = random(0, 10);
//if (PosY < 10) {
PosX = random(0, NUM_COLS - 1) << 8;
PosY = NUM_ROWS * 255;
SpeedY = 0;
//}
SpeedX = (((random()%2) * 2) - 1) * random(128,255) * (bool)(random()%6);
Fade = 1024;
Color = random(0, 70);
}
void boom() {
int maxX = pow(NUM_COLS / 6, 2), maxY = pow(NUM_ROWS / 6, 2);
int xoffset[3], yoffset[3];
for(uint8_t i = 0; i < 3; i++){
xoffset[i] = (i)?random(0,NUM_COLS / 6)*(((random()%2) * 2) - 1):0;
yoffset[i] = (i)?random(0,NUM_ROWS / 6)*(((random()%2) * 2) - 1):0;
} //Serial.println(String(xoffset)+ " " + String(yoffset) + " ");
for (int8_t x = -(NUM_COLS /4); x < NUM_COLS / 4; x++) {
for (int8_t y = -(NUM_ROWS / 4); y < NUM_ROWS / 4; y++) {
CRGB boomcol = CHSV(50, 120, constrain(map((x * x + y * y), 0, maxX + maxY, 255, 0), 0, 255));
for(uint8_t i = 0; i < 3; i++){
leds[XY(xoffset[i] + (PosX >> 8) + x, yoffset[i] + (PosY >> 8) + y)] += boomcol;
}
}
}
}
void phisics() {
SpeedY -= SpeedK;
if (SpeedDecX || SpeedX) {
if (SpeedX > 0)
SpeedX -= SpeedDecX;
else
SpeedX += SpeedDecX;
if (abs(SpeedX) <= SpeedDecX)
SpeedX = 0;
}
if (Board) {
if (PosX < 0 || PosX >= (NUM_COLS - 1) << 8) SpeedX = -SpeedX;
}
if (PosY < 0) {
SpeedY = -SpeedY;
}
float speedvectdist = sqrt(pow(SpeedX,2)+pow(SpeedY, 2));
if(speedvectdist >= limiter){
SpeedX = (SpeedX / speedvectdist) * limiter;
SpeedY = (SpeedY / speedvectdist) * limiter;}
PosX += SpeedX;
PosY += SpeedY;
Fade -= FadeSpK;
if ((SpeedY > 0 && SpeedY < 1 && PosY < 512) || Fade <= 32) {
if(PosY > 10)boom();
reg();
}
}
void render(CRGB Col) {
phisics();
if (PosX < ((NUM_ROWS - 1) << 8) && PosY >= 0)
if (PosX < ((NUM_COLS - 1) << 8) && PosX >= 0) {
CRGB color = Col;
wu_pixel(PosX, PosY, & color);
}
}
} dot[SPARKS_AM];
void draw() {
if (loadingFlag) {
for (byte i = 0; i < SPARKS_AM; i++) {
dot[i].reg();
dot[i].PosY = NUM_ROWS << 8;
dot[i].PosX = random(0, NUM_COLS - 1) << 8;
dot[i].Fade = random(0,1024);
}
loadingFlag = false;
}
fadeToBlackBy(leds, NUM_LEDS, 32);
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);
}
}