CodeHub
HomeUploadContact
Back to Hub

Snake game on oled display

April 9, 2026 Watch Tutorial

Wiring Schematic

Snake game on oled display wiring diagram

Hardware Required

  • Arduino Board
    Buy on Amazon

Source Code

Arduino / C++
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4
5// OLED display settings
6#define SCREEN_WIDTH 128
7#define SCREEN_HEIGHT 64
8#define OLED_RESET    -1
9Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
10
11// Joystick Pins for Arduino Mega
12#define JOY_X A0 
13#define JOY_Y A1
14#define JOY_BTN 2
15
16// Game variables
17#define BLOCK_SIZE 4
18#define MAX_SNAKE_LENGTH 100
19
20int snakeX[MAX_SNAKE_LENGTH];
21int snakeY[MAX_SNAKE_LENGTH];
22int snakeLength = 5;
23int direction = 1; // 0=Up, 1=Right, 2=Down, 3=Left
24
25int foodX;
26int foodY;
27int score = 0;
28bool gameOver = false;
29
30void setup() {
31  Serial.begin(9600);
32  pinMode(JOY_BTN, INPUT_PULLUP); // Use internal pullup for the button
33
34  // Initialize OLED
35  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
36    Serial.println(F("SSD1306 allocation failed"));
37    for(;;);
38  }
39  
40  display.clearDisplay();
41  display.setTextSize(1);
42  display.setTextColor(SSD1306_WHITE);
43  
44  // Title screen border
45  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
46  
47  display.setCursor(30, 25);
48  display.print("SNAKE GAME");
49  display.display();
50  delay(2000);
51
52  resetGame();
53}
54
55void loop() {
56  // 1. Check the button FIRST! This lets you restart anytime.
57  if (digitalRead(JOY_BTN) == LOW) {
58    resetGame();
59    delay(200); // A tiny delay to stop accidental double-clicks
60  }
61
62  // 2. If the game is over, just show the screen and stop moving
63  if (gameOver) {
64    displayGameOver();
65    return; 
66  }
67
68  // 3. Normal gameplay logic
69  readJoystick();
70  updateSnake();
71  checkCollisions();
72  drawGame();
73  
74  // Game Speed
75  delay(40); 
76}
77
78void resetGame() {
79  snakeLength = 5;
80  direction = 1; // Start moving right
81  score = 0;
82  gameOver = false;
83
84  // Initial snake position
85  for (int i = 0; i < snakeLength; i++) {
86    snakeX[i] = (SCREEN_WIDTH / 2) - (i * BLOCK_SIZE);
87    snakeY[i] = SCREEN_HEIGHT / 2;
88  }
89
90  spawnFood();
91}
92
93void spawnFood() {
94  // Spawn food inside the grid, avoiding the outer border
95  foodX = random(1, (SCREEN_WIDTH / BLOCK_SIZE) - 1) * BLOCK_SIZE;
96  foodY = random(1, (SCREEN_HEIGHT / BLOCK_SIZE) - 1) * BLOCK_SIZE;
97}
98
99void readJoystick() {
100  int xVal = analogRead(JOY_X);
101  int yVal = analogRead(JOY_Y);
102
103  // Custom Calibration Integration
104  // UP: xVal < 200
105  // DOWN: xVal > 800
106  // LEFT: yVal > 800
107  // RIGHT: yVal < 200
108
109  if (xVal < 200 && direction != 2) {
110    direction = 0; // Up
111  } else if (xVal > 800 && direction != 0) {
112    direction = 2; // Down
113  } else if (yVal > 800 && direction != 1) {
114    direction = 3; // Left
115  } else if (yVal < 200 && direction != 3) {
116    direction = 1; // Right
117  }
118}
119
120void updateSnake() {
121  // Move the body segments
122  for (int i = snakeLength - 1; i > 0; i--) {
123    snakeX[i] = snakeX[i - 1];
124    snakeY[i] = snakeY[i - 1];
125  }
126
127  // Move the head
128  if (direction == 0) snakeY[0] -= BLOCK_SIZE; // Up
129  if (direction == 1) snakeX[0] += BLOCK_SIZE; // Right
130  if (direction == 2) snakeY[0] += BLOCK_SIZE; // Down
131  if (direction == 3) snakeX[0] -= BLOCK_SIZE; // Left
132}
133
134void checkCollisions() {
135  // Wall collision (Border)
136  if (snakeX[0] < 0 || snakeX[0] >= SCREEN_WIDTH || 
137      snakeY[0] < 0 || snakeY[0] >= SCREEN_HEIGHT) {
138    gameOver = true;
139  }
140
141  // Self collision
142  for (int i = 1; i < snakeLength; i++) {
143    if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
144      gameOver = true;
145    }
146  }
147
148  // Food collision
149  if (snakeX[0] == foodX && snakeY[0] == foodY) {
150    score++;
151    if (snakeLength < MAX_SNAKE_LENGTH) {
152      snakeLength++;
153    }
154    spawnFood();
155  }
156}
157
158void drawGame() {
159  display.clearDisplay();
160
161  // Draw border
162  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
163
164  // Draw food
165  display.fillRect(foodX, foodY, BLOCK_SIZE, BLOCK_SIZE, SSD1306_WHITE);
166
167  // Draw snake
168  for (int i = 0; i < snakeLength; i++) {
169    display.fillRect(snakeX[i], snakeY[i], BLOCK_SIZE, BLOCK_SIZE, SSD1306_WHITE);
170  }
171
172  display.display();
173}
174
175void displayGameOver() {
176  display.clearDisplay();
177  
178  // Draw border
179  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
180
181  display.setTextSize(2);
182  display.setCursor(12, 12);
183  display.print("GAME OVER");
184  
185  display.setTextSize(1);
186  display.setCursor(20, 35);
187  display.print("Final Score: ");
188  display.print(score);
189  
190  display.setCursor(10, 50);
191  display.print("Click stick to play");
192  
193  display.display();
194}
Breadboard
Buy on Amazon
  • Joystick module
    Buy on Amazon
  • SSD1306 oled dipslay
    Buy on Amazon
  • Jumper wires
    Buy on Amazon
  • USB Cable
    Buy on Amazon