The allure of classic arcade games is timeless, and few are as iconic as Space Invaders. The simple yet addictive gameplay, combined with the nostalgia of early video gaming, makes it a favorite among retro gaming enthusiasts. But what if you could bring this classic to life yourself, on an Arduino board with an OLED display? In this blog post, we'll explore how to create a Space Invaders game using Arduino and a bit of creativity.
Arduino Board: In our example, we'll use the versatile ESP32, but other boards can work too.
OLED Display: A 128x64 or 128x32 pixel OLED display with I2C or SPI interface.
Pushbutton: This will serve as your trigger to shoot at the alien invaders.
Potentiometer: You'll use this component to control the movement of your spaceship.
Breadboard and Jumper Wires: Essential for connecting and prototyping your hardware.
(Optional) Piezo Buzzer: For adding engaging sound effects to your game.
Game Logic and Components
Display Initialization: Initialize the OLED display to set the stage for rendering the game's graphics.
Spaceship: Create your spaceship at the bottom of the display. The potentiometer controls its position on the X-axis.
Alien Invaders: Populate the top of the display with alien invaders. These extraterrestrial foes move horizontally and descend systematically.
Shooting Mechanism: Implement a shooting mechanism for your spaceship. Press the pushbutton to fire bullets at the invaders.
Gameplay: Your objective is to shoot down the descending invaders. For every successful hit, your score increases. If an invader reaches the bottom of the screen or collides with your spaceship, you lose a life. Keep track of your score and remaining lives.
Display Updates: Continually update the display to show the game's current state. Draw your spaceship, invaders, bullets, score, and lives.
Game Over: Implement game-over conditions. When you run out of lives, display a "Game Over" message on the OLED screen. Allow players to restart by pressing a button.
Game Loop: Set up a game loop that controls the frame rate, updates game elements, and handles player input.
(Optional) Sound Effects: Add sound effects for shooting, alien movements, or game-over events using a piezo buzzer or a speaker.
/**************************************
* Project: Space Invaders Game
* Author: Shakil Tanvir
* Date: 24 October 2023
* Copyright © 20[XX] Shakil Tanvir. All rights reserved.
* Permission is hereby granted for personal and educational use only.
* Commercial use of this code or any derivative works is strictly prohibited without written consent from the author.
* Make Sure the pin no and your ADC chanel is 10bit or you can map your adc values from the code
**************************************/
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Initialize the OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Spaceship variables
int spaceshipX = SCREEN_WIDTH / 2;
int spaceshipY = SCREEN_HEIGHT - 10;
int spaceshipWidth = 10;
int spaceshipHeight = 5;
// Bullet variables
int bulletX;
int bulletY;
int bulletSpeed = 2;
boolean bulletFired = false;
// Alien invader variables
int alienX = random(0, SCREEN_WIDTH);
int alienY = 0;
int alienSpeed = 1;
int alienWidth = 10;
int alienHeight = 5;
// Game variables
int score = 0;
int lives = 3;
// Button and potentiometer pins
int buttonPin = 2; // Change to the pin you're using
int potentiometerPin = A0; // Change to the pin you're using
void setup() {
display.begin(SSD1306_I2C_ADDRESS, 4, 5);
display.display();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Space Invaders");
display.display();
delay(2000); // Display the title for 2 seconds
// Initialize the button pin
pinMode(buttonPin, INPUT);
}
void loop() {
// Read the potentiometer value to move the spaceship
int potValue = analogRead(potentiometerPin);
spaceshipX = map(potValue, 0, 1023, 0, SCREEN_WIDTH - spaceshipWidth);
// Check if the button is pressed to fire a bullet
if (digitalRead(buttonPin) == HIGH && !bulletFired) {
bulletX = spaceshipX + spaceshipWidth / 2;
bulletY = spaceshipY;
bulletFired = true;
}
// Move the bullet
if (bulletFired) {
bulletY -= bulletSpeed;
if (bulletY < 0) {
bulletFired = false;
}
}
// Move the alien invader
alienY += alienSpeed;
if (alienY > SCREEN_HEIGHT) {
alienX = random(0, SCREEN_WIDTH);
alienY = 0;
}
// Check for collisions
if (collide(bulletX, bulletY, 2, 2, alienX, alienY, alienWidth, alienHeight)) {
score++;
alienX = random(0, SCREEN_WIDTH);
alienY = 0;
bulletFired = false;
}
if (collide(spaceshipX, spaceshipY, spaceshipWidth, spaceshipHeight, alienX, alienY, alienWidth, alienHeight)) {
lives--;
alienX = random(0, SCREEN_WIDTH);
alienY = 0;
}
// Clear the display
display.clearDisplay();
// Draw game elements
display.drawRect(spaceshipX, spaceshipY, spaceshipWidth, spaceshipHeight, SSD1306_WHITE);
display.drawCircle(bulletX, bulletY, 2, SSD1306_WHITE);
display.drawRect(alienX, alienY, alienWidth, alienHeight, SSD1306_WHITE);
// Display score and lives
display.setCursor(0, 0);
display.print("Score: ");
display.print(score);
display.setCursor(SCREEN_WIDTH - 50, 0);
display.print("Lives: ");
display.print(lives);
display.display();
// Check for game over
if (lives <= 0) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20, SCREEN_HEIGHT / 2 - 10);
display.print("Game Over");
display.display();
delay(2000); // Display "Game Over" for 2 seconds
resetGame();
}
delay(20); // Adjust the game speed by changing the delay
}
boolean collide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
return (x1 + w1 >= x2 && x1 <= x2 + w2 && y1 + h1 >= y2 && y1 <= y2 + h2);
}
void resetGame() {
score = 0;
lives = 3;
spaceshipX = SCREEN_WIDTH / 2;
alienX = random(0, SCREEN_WIDTH);
alienY = 0;
display.clearDisplay();
}
During the development phase, it's essential to test your game regularly and debug any issues that arise. Ensure that the hardware components, such as the potentiometer and pushbutton, are correctly integrated and responsive.
Make Sure the pin no and your ADC chanel is 10bit or you can map your adc values from the code
Design the visual elements of your game, including the spaceship, aliens, bullets, and any additional graphics you'd like to include. Utilize simple shapes or images to represent these elements on the OLED display.