#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
struct Spark {
int x, y, dx, dy, life;
};
Spark sparks[40];
int stage = 0;
unsigned long stageStart = 0;
int rocketY = 54;
int zoomSize = 1;
int flameFrame = 0;
int glow = 0, dir = 1;
bool exploded = false;
void newExplosion(int cx, int cy) {
for (int i = 0; i < 40; i++) {
sparks[i].x = cx;
sparks[i].y = cy;
sparks[i].dx = random(-4, 5);
sparks[i].dy = random(-3, 4);
sparks[i].life = random(10, 25);
}
}
void drawDiya(int x, int y, int flameFrame) {
display.drawLine(x - 14, y, x + 14, y, WHITE);
display.drawLine(x - 12, y - 2, x + 12, y - 2, WHITE);
display.drawLine(x - 10, y - 3, x + 10, y - 3, WHITE);
display.drawLine(x - 8, y - 4, x + 8, y - 4, WHITE);
display.drawLine(x - 6, y - 5, x + 6, y - 5, WHITE);
display.drawLine(x - 4, y - 6, x + 4, y - 6, WHITE);
display.drawLine(x - 2, y - 7, x + 2, y - 7, WHITE);
display.drawCircle(x - 12, y - 2, 2, WHITE);
display.drawCircle(x + 12, y - 2, 2, WHITE);
display.drawLine(x, y - 8, x, y - 11, WHITE);
int f = flameFrame % 4;
display.fillTriangle(x, y - 11 - f, x - 2, y - 8, x + 2, y - 8, WHITE);
if (f % 2 == 0) display.drawLine(x, y - 11 - f, x, y - 13 - f, WHITE);
}
void drawMuggu() {
for (int i = 0; i < 128; i += 16) {
display.drawCircle(i + 8, 8, 2, WHITE);
display.drawCircle(i + 8, 56, 2, WHITE);
}
for (int j = 0; j < 64; j += 16) {
display.drawCircle(8, j + 8, 2, WHITE);
display.drawCircle(120, j + 8, 2, WHITE);
}
display.drawRect(2, 2, 124, 60, WHITE);
}
void rocketStage() {
display.drawLine(64, rocketY, 64, rocketY + 8, WHITE);
rocketY -= 4;
if (rocketY < 10) {
newExplosion(64, 12);
stage = 1;
stageStart = millis();
}
}
void explosionStage() {
bool alive = false;
for (int i = 0; i < 40; i++) {
if (sparks[i].life > 0) {
sparks[i].x += sparks[i].dx;
sparks[i].y += sparks[i].dy;
sparks[i].dy += 1;
sparks[i].life--;
if (sparks[i].life > 0)
display.drawPixel(sparks[i].x, sparks[i].y, WHITE);
alive = true;
}
}
if (!alive && millis() - stageStart > 2500) {
stage = 2;
stageStart = millis();
}
}
void mugguStage() {
drawMuggu();
drawDiya(64, 54, flameFrame);
flameFrame++;
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(25, 25);
display.print("✨ HAPPY DIWALI ✨");
if (millis() - stageStart > 4000) {
stage = 3;
stageStart = millis();
zoomSize = 1;
}
}
void vectorStage() {
display.setTextColor(WHITE);
display.setTextSize(zoomSize);
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds("Vector India", 0, 0, &x1, &y1, &w, &h);
int x = (SCREEN_WIDTH - w) / 2;
int y = (SCREEN_HEIGHT - h) / 2;
display.setCursor(x, y);
display.print("Vector India");
display.setTextSize(zoomSize - 1);
display.setCursor(x + 8, y + 15);
display.print("Hyderabad");
if (millis() - stageStart > 120) {
zoomSize++;
stageStart = millis();
}
if (zoomSize > 3) {
stage = 0;
stageStart = millis();
rocketY = 54;
}
}
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
randomSeed(analogRead(0));
stageStart = millis();
}
void loop() {
display.clearDisplay();
switch (stage) {
case 0: rocketStage(); break;
case 1: explosionStage(); break;
case 2: mugguStage(); break;
case 3: vectorStage(); break;
}
display.display();
delay(60);
}