#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];
#define scale (8)
#define board (0)
#define trace (1)
#define Go_horizontal (1)
#define LIGHTERS_AM WIDTH*2
int lightersPosX[LIGHTERS_AM];
int lightersPosY[LIGHTERS_AM];
float lightersSpeedX[LIGHTERS_AM];
float lightersSpeedY[LIGHTERS_AM];
byte lcolor[LIGHTERS_AM];
byte mass[LIGHTERS_AM];
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 drawPixelXYF_Y(uint16_t x, float y, const CRGB &color)
{
if (x<0 || y<0 || x>((float)WIDTH) || y>((float)HEIGHT)) return;
// extract the fractional parts and derive their inverses
uint8_t yy = (y - (int)y) * 255, iy = 255 - yy;
// calculate the intensities for each affected pixel
uint8_t wu[2] = {iy, yy};
// multiply the intensities by the colour, and saturating-add them to the pixels
for (int8_t i = 1; i >= 0; i--) {
int16_t yn = y + (i & 1);
CRGB clr = leds[XY(x, yn)];
if(yn>0 && yn<(int)HEIGHT-1){
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);
} else if(yn==0 || yn==(int)HEIGHT-1) {
clr.r = qadd8(clr.r, (color.r * 85) >> 8);
clr.g = qadd8(clr.g, (color.g * 85) >> 8);
clr.b = qadd8(clr.b, (color.b * 85) >> 8);
}
leds[XY(x, yn)] = clr;
}
}
bool loadingFlag = true;
bool boom;
void reg(byte id) {
if (Go_horizontal)lightersSpeedX[id] = random(-20, 20);else lightersSpeedX[id] = 0;
lightersSpeedY[id] = random(20);
lcolor[id] = random();
}
void phisics(byte id) {
// lcolor[id] = random();
lightersPosX[id] += lightersSpeedX[id];
lightersPosY[id] += lightersSpeedY[id];
lightersSpeedY[id] -= .98*mass[id]/128;
if (lightersSpeedX[id] < 0 || lightersSpeedX[id] > 0) {
if (lightersSpeedX[id] > 0)
lightersSpeedX[id] -= 0.1;
else
lightersSpeedX[id] += 0.1;
}
if (lightersPosY[id] < 0) {
lightersSpeedY[id] = -lightersSpeedY[id] * 0.9;
}
if(board){
if (lightersPosX[id] <= 0 || lightersPosX[id] >= (WIDTH-1) * 10) {
lightersSpeedX[id] = -lightersSpeedX[id];
}}else{if (lightersPosX[id] < 0)lightersPosX[id] = (WIDTH-1)*10;if (lightersPosX[id] > (WIDTH-1)*10)lightersPosX[id] = 0;}
if (lightersSpeedY[id] > 0 && lightersSpeedY[id]< 1 && lightersPosY[id]<20)
reg(id);
}
void draw() {
if (loadingFlag) {
for (byte i = 0; i < map(scale, 1, 16, 1, LIGHTERS_AM); i++) {
reg(i);
mass[i] = random(64,255);
lightersPosX[i] = random(0,(WIDTH-1)*10);
lightersPosY[i] = random(0,(HEIGHT-1)*10);
}
loadingFlag = false;
}
if(trace)fadeToBlackBy(leds, NUM_LEDS, 80);else FastLED.clear();
for (byte i = 0; i < map(scale, 1, 16, 1, LIGHTERS_AM); i++) {
phisics(i);
if (lightersPosY[i] < ((HEIGHT - 1) * 10)){
if (lightersPosX[i] < ((WIDTH - 1) * 10) && lightersPosX[i] > 0)
if(lightersSpeedX[i]==0)
drawPixelXYF_Y((float)lightersPosX[i] / 10, ((float)lightersPosY[i] / 10), CHSV(lcolor[i], 255, 255));
else drawPixelXYF((float)lightersPosX[i] / 10, ((float)lightersPosY[i] / 10), CHSV(lcolor[i], 255, 255));
}}
}
void setup() {
//Serial.begin(250000);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
draw();
FastLED.show();
//static int frame = 0;
//if (frame++ % 32 == 0)
// Serial.println(FastLED.getFPS());
} //loop
uint16_t XY (uint8_t x, uint8_t y) {
if(x >= WIDTH || y >= HEIGHT) return;
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);
}
}