#include "FastLED.h"

// Matrix size
#define LED_ROWS 16
#define LED_COLS 16
#define NUM_LEDS LED_ROWS * LED_COLS
// LEDs pin
#define DATA_PIN 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS];

bool setUp = true; 
#define n ((NUM_LEDS > 128) ? NUM_LEDS / 128 : 1 )
int posX[n];
int posY[n];
int aimX[n];
int aimY[n];
const uint8_t speed = (NUM_LEDS < 256) ? 1 :(NUM_LEDS < 1026) ? NUM_LEDS / 256 : 4;

byte hue[n];
void aimchange(byte id){
aimX[id]=random(0,(LED_COLS-1)*4);
aimY[id]=random(0,(LED_ROWS-1)*4);
hue[id] = random();
}

void setUpp(){
for(byte i = 0; i < n; i++){
posX[i]=random(0,(LED_COLS-1)*4);
posY[i]=random(0,(LED_ROWS-1)*4);
aimchange(i);
}
}
void draw() {
  if (setUp){
    setUp = false;
    setUpp();
  }
  fadeToBlackBy(leds, NUM_LEDS, 10);
  blur2d(leds, LED_COLS, LED_ROWS, 16);
  for(byte i = 0; i < n; i++){
  if(round(posX[i]/4)>round(aimX[i]/4)){ posX[i]-=speed;}
  if(round(posY[i]/4)>round(aimY[i]/4)){ posY[i]-=speed;}
  if(round(posX[i]/4)<round(aimX[i]/4)){ posX[i]+=speed;}
  if(round(posY[i]/4)<round(aimY[i]/4)){ posY[i]+=speed;}
  if(round(posX[i]/4)==round(aimX[i]/4) && round(posY[i]/4)==round(aimY[i]/4)){aimchange(i);} 
  leds[XY(posX[i]/4,posY[i]/4)] = CHSV(hue[i],60,255);
leds[XY(aimX[i]/4+1,aimY[i]/4)] = CHSV(hue[i],255,255);
leds[XY(aimX[i]/4,aimY[i]/4+1)] = CHSV(hue[i],255,255);
leds[XY(aimX[i]/4-1,aimY[i]/4)] = CHSV(hue[i],255,255);
leds[XY(aimX[i]/4,aimY[i]/4-1)] = CHSV(hue[i],255,255);
}}
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) {
  return (y * LED_COLS + x);
}