Boring Ball — ESP8266 + 0.96" I2C OLED (SSD1306)

What this is
------------
I built a tiny one-button OLED game called “Boring Ball”. The ball rests on the bottom edge. 
When I press the button, it launches upward in a random upward direction, bounces off the
side walls and the top, and finally returns to rest on the bottom. The game screen shows
only my background image and the ball (no HUD or extra text). On the welcome screen, the
title shows on two centered lines with both words in bold italic:
    Boring
    Ball

Hardware I used
----------------
- LOLIN (Wemos) D1 mini – ESP8266
- 0.96" 128×64 OLED (SSD1306, I2C, 4‑pin)
- 1 × Momentary push button (NO type)
- Jumper wires, breadboard (optional)

Libraries & IDE
----------------
- Arduino IDE
- Adafruit GFX Library
- Adafruit SSD1306 Library

Code (overview)
---------------
- I’m using Adafruit SSD1306 + GFX.
- I2C address: default 0x3C (I also keep 0x3D as a fallback in code).
- I draw the title on the welcome screen using FreeSansBoldOblique12pt7b so both words
  (“Boring” and “Ball”) appear bold and italic on separate centered lines.
- After a short delay, the game starts automatically. The game screen has no text; only
  the background bitmap and the 16×16 ball.
- Physics is simple: gravity pulls the ball down; the ball bounces from side walls and
  the top; at the bottom it settles so it rests on the last pixel row.
- I seed randomness and pick an upward-biased launch angle; launch speed is chosen so
  the ball can reach the top.

Assets I included
-----------------
- Ball bitmap (16×16, 1‑bit) generated via imag2cpp:
    const unsigned char epd_bitmap_8888[] PROGMEM = {
        0xff, 0xff, 0xf8, 0x1f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
        0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff
    };
- Background bitmap (128×64, 1‑bit) in a PROGMEM array named:
    const unsigned char epd_bitmap_Untitled_2[] PROGMEM = { /* 128x64 data */ };

Pinout & Connections
--------------------
OLED (SSD1306)  →  D1 mini (ESP8266)
- VCC           →  3V3
- GND           →  G
- SCL/SCK       →  D1  (GPIO5)
- SDA           →  D2  (GPIO4)

Button (NO)     →  D1 mini (ESP8266)
- One leg       →  D5  (GPIO14)
- Other leg     →  GND

I use INPUT_PULLUP for the button, so the pin reads HIGH when idle and LOW when pressed.
Avoid boot-critical pins (D3/D4/D8) for the button to keep boot reliable.

Build & Flash
-------------
1) Install the two Adafruit libraries from Library Manager.
2) Select “LOLIN (WEMOS) D1 R2 & mini” as the board in Arduino IDE.
3) Wire the OLED and button as shown above.
4) In setup(), I call Wire.begin(D2, D1) to set I2C pins explicitly.
5) Upload the sketch.

Game Behavior (quick notes)
---------------------------
- Welcome screen shows only the two-line title (bold italic), centered, then the game begins.
- Game screen: no text, only the background and the 16×16 ball.
- The ball rests with its bottom touching the last display row (y = 63).
- When I press the button (from rest), the ball launches up in a random upward direction.
- The ball can reach the top; it bounces off walls and top, then comes back down and rests.

Troubleshooting
---------------
- If the OLED stays blank, I check the I2C address (0x3C vs 0x3D) and the SDA/SCL wiring.
- If the ball doesn’t move, I verify the button wiring (D5 to GND) and that INPUT_PULLUP is set.
- If fonts don’t render, I confirm the Adafruit GFX fonts are installed and included.

Notes
-----
- I keep wires short for I2C stability.
- If I change the ball image, I regenerate a 1‑bit bitmap with imag2cpp and update the array.
- For a lighter or heavier feel, I tweak GRAVITY and the initial launch speed.
