Little snow Demo, uses also the Lights.


Download: Snow.zip


BUTTON_MENU = reset the Snow

BUTTON_A = 160x128, index

BUTTON_B= 80x64, index

BUTTON_UP = Temperature + 

BUTTON_DOWN = Temperature -

BUTTON_LEFT = Speed -

BUTTON_RIGHT = Speed +



#include 
#define NUM_PARTICLES 1300
#define MAX_TTL 2000
#define MIN_TTL MAX_TTL/2
int particleCount = 0;

typedef struct {
  byte x;
  byte y;
  int ttl;
  byte color;
} particle;

particle particles[NUM_PARTICLES];
int temperature = 1;
byte snowSpeed = 1;
void setup()
{
  gb.begin();
  gb.lights.clear();
  randomSeed(analogRead(A2));
  gb.display.init(160, 128, ColorMode::index);
  resetParticles();
}

void loop() {
  while (!gb.update());
  gb.display.clear();

  if (gb.buttons.pressed(BUTTON_A)) {
    gb.display.init(160, 128, ColorMode::index);
  }

  if (gb.buttons.pressed(BUTTON_B)) {
    gb.display.init(80, 64, ColorMode::index);
  }

  if (gb.buttons.pressed(BUTTON_MENU)) {
    resetParticles();
  }
  if (gb.buttons.pressed(BUTTON_UP)) {
    if (temperature < 50)
      temperature++;
  }
  if (gb.buttons.pressed(BUTTON_DOWN)) {
    if (temperature > -50)
      temperature--;
  }

  if (gb.buttons.pressed(BUTTON_LEFT)) {
    if (snowSpeed < 10)
      snowSpeed++;
  }
  if (gb.buttons.pressed(BUTTON_RIGHT)) {
    if (snowSpeed > 0)
      snowSpeed--;
  }
  if ((random(0, snowSpeed) + 1) == 1 && (10 - snowSpeed) != 0)
    createParticles();

  drawParticles();

  updateParticles();
  gb.display.print("T:");
  gb.display.print(temperature);
  gb.display.println("C");
  gb.display.print("S:");
  gb.display.println(10 - snowSpeed);
}

void resetParticles() {
  gb.display.clear();
  gb.lights.clear();
  for (int i = 0; i < NUM_PARTICLES; i++) {
    particles[i].x = -1;
    particles[i].y = -1;
  }
  particleCount = 0;
}

void createParticles() {
  if (particleCount < NUM_PARTICLES) {
    initParticles(particleCount);
    particleCount++;
  }
}

void initParticles(int n) {
  if (n < NUM_PARTICLES) {
    particles[n].x = random(0, gb.display.width() - 1);
    particles[n].y = 1;
    particles[n].ttl = random(MIN_TTL, MAX_TTL);
    particles[n].color = 0;
  }
}

void updateParticles() {
  for (int i = 0; i < particleCount; i++) {
    if (particles[i].y >= 0 && particles[i].y < gb.display.height() - 1) {
      if ((int)gb.display.getPixel(particles[i].x , particles[i].y + 1) == (int)BLACK) {
        particles[i].y++;
      }
      else {
        if (((int)gb.display.getPixel(particles[i].x - 1 , particles[i].y + 1) == (int)BLACK && (int)gb.display.getPixel(particles[i].x - 1 , particles[i].y) == (int)BLACK) && ((int)gb.display.getPixel(particles[i].x + 1 , particles[i].y + 1) == (int)BLACK && (int)gb.display.getPixel(particles[i].x + 1 , particles[i].y) == (int)BLACK)) {
          if (random(0, 2) >= 1)
            particles[i].x--;
          else
            particles[i].x++;
        } else {
          if ((int)gb.display.getPixel(particles[i].x - 1 , particles[i].y + 1) == (int)BLACK && (int)gb.display.getPixel(particles[i].x - 1 , particles[i].y) == (int)BLACK) {
            particles[i].x--;
            if (random(0, 2) >= 1)
              gb.lights.drawPixel(0, random(0, 5), WHITE);
            else
              gb.lights.drawPixel(0, random(0, 5), BLACK);
          }
          if ((int)gb.display.getPixel(particles[i].x + 1 , particles[i].y + 1) == (int)BLACK && (int)gb.display.getPixel(particles[i].x + 1 , particles[i].y) == (int)BLACK) {
            particles[i].x++;
            if (random(0, 2) >= 1)
              gb.lights.drawPixel(1, random(0, 5), WHITE);
            else
              gb.lights.drawPixel(1, random(0, 5), BLACK);
          }
        }
      }
    }
    if (particles[i].ttl > 0) {
      if (particles[i].ttl <= MAX_TTL)
        particles[i].ttl = particles[i].ttl - temperature;
      else {
        particles[i].ttl = MAX_TTL;
        particles[i].color = 0;
      }

      if (particles[i].ttl < MAX_TTL / 4)
        particles[i].color = 3;
      else if (particles[i].ttl < MAX_TTL / 3)
        particles[i].color = 2;
      else if (particles[i].ttl < MAX_TTL / 2)
        particles[i].color = 1;
    }
    else {
      initParticles(i);
    }

    if (particles[i].y < 0 && particles[i].y > gb.display.height() - 1)
      initParticles(i);
  }
}

void drawParticles() {
  for (int i = 0; i < particleCount; i++) {
    if (particles[i].x >= 0 && particles[i].y >= 0 && particles[i].x < gb.display.width() && particles[i].y < gb.display.height()) {
      if (particles[i].color == 0)
        gb.display.drawPixel(particles[i].x, particles[i].y, WHITE);
      if (particles[i].color == 1)
        gb.display.drawPixel(particles[i].x, particles[i].y, LIGHTBLUE);
      if (particles[i].color == 2)
        gb.display.drawPixel(particles[i].x, particles[i].y, BLUE);
      if (particles[i].color == 3)
        gb.display.drawPixel(particles[i].x, particles[i].y, DARKBLUE);
    } else {
      initParticles(i);
    }
  }
}