#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define W 128
#define H 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(W, H, &Wire, OLED_RESET);
/* ---- TEXT GEOMETRY ---- */
#define TXT_Y 22
#define DIGIT_W 18
#define DIGIT_H 24
int digitX[4] = {22, 40, 58, 76}; // positions for digits
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
randomSeed(analogRead(A0));
}
void loop() {
show2025();
snakeEat2025Smooth();
airBombs();
snakeReveal2026Smooth();
finalWish();
}
/* ---------------- SHOW 2025 ---------------- */
void show2025() {
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(SSD1306_WHITE);
display.setCursor(digitX[0], TXT_Y);
display.print("2025");
display.display();
delay(1500);
}
/* ---------------- SMOOTH SNAKE EATING 2025 ---------------- */
void snakeEat2025Smooth() {
for (int headX = -10; headX <= W + 10; headX++) {
display.clearDisplay();
/* Draw full 2025 */
display.setTextSize(3);
display.setCursor(digitX[0], TXT_Y);
display.print("2025");
/* Smooth erase using mask */
int maskW = constrain(headX - digitX[0], 0, 4 * DIGIT_W);
display.fillRect(digitX[0], TXT_Y, maskW, DIGIT_H, SSD1306_BLACK);
drawSnake(headX, true);
display.display();
delay(20); // smaller delay = smoother
}
display.clearDisplay();
display.display();
}
/* ---------------- AIR BOMB BLASTS ---------------- */
void airBombs() {
for (int i = 0; i < 4; i++) {
int cx = random(20, W - 20);
int cy = random(8, 28);
for (int r = 2; r < 26; r++) {
display.clearDisplay();
display.drawCircle(cx, cy, r, SSD1306_WHITE);
for (int s = 0; s < 10; s++) {
display.drawPixel(cx + random(-r, r),
cy + random(-r, r),
SSD1306_WHITE);
}
display.display();
delay(25);
}
}
}
/* ---------------- SMOOTH SNAKE REVEAL 2026 ---------------- */
void snakeReveal2026Smooth() {
for (int headX = W + 10; headX >= -10; headX--) {
display.clearDisplay();
/* Draw full 2026 */
display.setTextSize(3);
display.setCursor(digitX[0], TXT_Y);
display.print("2026");
/* Smooth reveal mask (RIGHT → LEFT) */
int revealW = constrain((digitX[0] + 4 * DIGIT_W) - headX,
0, 4 * DIGIT_W);
display.fillRect(digitX[0], TXT_Y,
4 * DIGIT_W - revealW,
DIGIT_H,
SSD1306_BLACK);
drawSnake(headX, false);
display.display();
delay(20);
}
}
/* ---------------- DRAW SNAKE ---------------- */
void drawSnake(int headX, bool leftToRight) {
int dir = leftToRight ? -1 : 1;
for (int i = 0; i < 22; i += 4) {
display.fillCircle(headX + dir * i, 36, 3, SSD1306_WHITE);
}
display.fillCircle(headX, 36, 4, SSD1306_WHITE);
display.drawPixel(headX + (leftToRight ? 2 : -2), 35, SSD1306_BLACK);
}
/* ---------------- FINAL WISH ---------------- */
void finalWish() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(20, 2);
display.print("HAPPY NEW YEAR");
display.setTextSize(3);
display.setCursor(digitX[0], TXT_Y);
display.print("2026");
display.display();
delay(4000);
}