#include <Wire.h>
#include <U8g2lib.h>
// Screen dimensions
constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 64;
// Display instance (hardware I2C)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
// Brick layout constants
constexpr uint8_t BRICK_ROWS = 2;
constexpr uint8_t BRICK_COLS = 10;
constexpr uint8_t BRICK_SPACING = 2;
constexpr uint8_t BRICK_HEIGHT = 4;
constexpr uint8_t BRICK_TOP_OFFSET = 0;
constexpr uint8_t BRICK_WIDTH = (SCREEN_WIDTH - (BRICK_COLS - 1) * BRICK_SPACING) / BRICK_COLS;
// Paddle constants
constexpr uint8_t PADDLE_WIDTH = 30;
constexpr uint8_t PADDLE_HEIGHT = 4;
constexpr uint8_t PADDLE_MARGIN = 1; // bottom margin
// Ball constants
constexpr uint8_t BALL_RADIUS = 3;
constexpr uint8_t BALL_PADDLE_GAP = 6;
// Function prototypes
void initDisplay();
void drawBricks();
void drawPaddle();
void drawBall();
void drawScene();
void setup()
{
initDisplay();
}
void loop()
{
drawScene();
// Keep static display
while (true)
{
delay(100);
}
}
void initDisplay()
{
Wire.begin();
u8g2.begin();
}
void drawBricks()
{
for (uint8_t r = 0; r < BRICK_ROWS; ++r)
{
for (uint8_t c = 0; c < BRICK_COLS; ++c)
{
uint8_t x = c * (BRICK_WIDTH + BRICK_SPACING);
uint8_t y = BRICK_TOP_OFFSET + r * (BRICK_HEIGHT + BRICK_SPACING);
u8g2.drawFrame(x, y, BRICK_WIDTH, BRICK_HEIGHT);
u8g2.drawBox(x + 1, y + 1, BRICK_WIDTH - 2, BRICK_HEIGHT - 2);
}
}
}
void drawPaddle()
{
uint8_t x = (SCREEN_WIDTH - PADDLE_WIDTH) / 2;
uint8_t y = SCREEN_HEIGHT - PADDLE_MARGIN - PADDLE_HEIGHT;
u8g2.drawBox(x, y, PADDLE_WIDTH, PADDLE_HEIGHT);
}
void drawBall()
{
uint8_t x = SCREEN_WIDTH / 2;
uint8_t y = SCREEN_HEIGHT - PADDLE_MARGIN - PADDLE_HEIGHT - BALL_PADDLE_GAP;
u8g2.drawDisc(x, y, BALL_RADIUS);
}
void drawScene()
{
u8g2.clearBuffer();
drawBricks();
drawPaddle();
drawBall();
u8g2.sendBuffer();
}