고급⏱ 예상 시간: 50분📝 6단계
OLED 미니 게임기
조이스틱으로 OLED 화면 위의 캐릭터를 움직여 장애물을 피하는 간단한 미니 게임을 만듭니다.
🧩 필요한 모듈
Arduino Uno
브레드보드
피에조 부저
조이스틱 모듈
점퍼 와이어
OLED 디스플레이 (0.96인치 I2C)
저항 (220Ω / 10kΩ)
📖 단계별 설명서
1단계준비물 확인
다음 부품들을 준비해주세요:
- Arduino Uno 1개
- 브레드보드 1개
- 점퍼 와이어 10개
- OLED 디스플레이 (0.96인치 I2C) 1개
- 조이스틱 모듈 1개
- 피에조 부저 1개
- 저항 (필요시)
2단계회로 연결하기
- OLED의 SDA를 A4, SCL을 A5에 연결합니다.
- OLED의 VCC를 5V, GND를 GND에 연결합니다.
- 조이스틱의 VRx를 A0, VRy를 A1에 연결합니다.
- 조이스틱의 SW를 D2에 연결합니다 (내장 풀업 사용).
- 조이스틱의 +5V를 5V, GND를 GND에 연결합니다.
- 부저를 D8에 연결합니다.
📐 회로도
회로도 이미지
/images/projects/oled-game-circuit.png
3단계라이브러리 설치
아두이노 IDE 라이브러리 관리에서:
Adafruit SSD1306설치Adafruit GFX Library설치
4단계코드 작성하기
code.ino
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_W 128
#define SCREEN_H 64
Adafruit_SSD1306 display(SCREEN_W, SCREEN_H, &Wire, -1);
const int JOY_X = A0;
const int JOY_BTN = 2;
const int BUZZER = 8;
// Player
int playerX = 10;
int playerY = 32;
const int playerSize = 6;
// Obstacles
const int MAX_OBS = 4;
int obsX[MAX_OBS];
int obsY[MAX_OBS];
int obsH[MAX_OBS];
int obsSpeed = 2;
int score = 0;
bool gameOver = false;
unsigned long lastFrame = 0;
void resetGame() {
playerY = 32;
score = 0;
obsSpeed = 2;
gameOver = false;
for (int i = 0; i < MAX_OBS; i++) {
obsX[i] = SCREEN_W + i * 40;
obsY[i] = random(10, SCREEN_H - 20);
obsH[i] = random(8, 20);
}
}
void setup() {
pinMode(JOY_BTN, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
randomSeed(analogRead(A2));
resetGame();
}
void loop() {
if (millis() - lastFrame < 33) return; // ~30fps
lastFrame = millis();
if (gameOver) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(15, 10);
display.print("GAME OVER");
display.setTextSize(1);
display.setCursor(35, 35);
display.print("Score: ");
display.print(score);
display.setCursor(20, 50);
display.print("Press to restart");
display.display();
if (digitalRead(JOY_BTN) == LOW) {
delay(300);
resetGame();
}
return;
}
// Read joystick Y axis
int joyVal = analogRead(JOY_X); // Using X for vertical
if (joyVal < 400) playerY -= 3;
if (joyVal > 600) playerY += 3;
playerY = constrain(playerY, 0, SCREEN_H - playerSize);
// Update obstacles
for (int i = 0; i < MAX_OBS; i++) {
obsX[i] -= obsSpeed;
if (obsX[i] < -10) {
obsX[i] = SCREEN_W + random(10, 30);
obsY[i] = random(5, SCREEN_H - 20);
obsH[i] = random(8, 20);
score++;
tone(BUZZER, 2000, 30);
// Increase speed every 5 points
if (score % 5 == 0 && obsSpeed < 6) obsSpeed++;
}
// Collision detection
if (obsX[i] < playerX + playerSize &&
obsX[i] + 6 > playerX &&
obsY[i] < playerY + playerSize &&
obsY[i] + obsH[i] > playerY) {
gameOver = true;
tone(BUZZER, 200, 500);
}
}
// Draw
display.clearDisplay();
// Ground line
display.drawLine(0, SCREEN_H - 1, SCREEN_W, SCREEN_H - 1, SSD1306_WHITE);
// Player (square)
display.fillRect(playerX, playerY, playerSize, playerSize, SSD1306_WHITE);
// Obstacles
for (int i = 0; i < MAX_OBS; i++) {
display.fillRect(obsX[i], obsY[i], 6, obsH[i], SSD1306_WHITE);
}
// Score
display.setTextSize(1);
display.setCursor(90, 2);
display.print("S:");
display.print(score);
display.display();
}+110 줄 더 보기
5단계업로드 및 테스트
- 코드를 업로드합니다.
- 조이스틱을 위아래로 움직여 캐릭터(사각형)를 조종합니다.
- 오른쪽에서 다가오는 장애물을 피합니다.
- 충돌하면 GAME OVER 화면이 나타납니다.
- 조이스틱 버튼을 누르면 재시작합니다.
💡 팁: score가 올라갈수록 속도가 빨라집니다! 최고 점수에 도전해보세요.
6단계심화 — 하이스코어 저장
EEPROM 라이브러리를 사용하면 최고 점수를 저장하여 전원을 꺼도 기록이 유지됩니다.