The object of the game is to shoot the LDR (target) under the active LED with a light beam from a laser pointer.

This time I will show you how to make a simple but addictive game for one or more players. The game consists of the following:

We have five blue LEDs that light at random order and intervals. Under each LED is a photoresistor that is actually a target. The object of the game is to shoot the LDR (target) under the active LED with a light beam from a laser pointer. As soon as you hit this LDR, the corresponding LED goes out.

https://www.pcbgogo.com/promo/from_MirkoPavleskiMK

You need to shoot as many targets as possible. You get one point and one more shot for each destroyed Target (at the beginning of the game you have 5 points). The game is lost if you fail to shoot down a target (too slow) or if you run out of ammunition. The course of the game is accompanied by appropriate sounds for the start, hit the target, or end of the game. Basically, the code is taken from the elektro.turanis.de site, and I added an I2C LCD display so that instead of the serial monitor, the result is displayed on the display, so now this is a standalone device.

Otherwise, the device is very simple to make and contains only a few components:

- Arduino nano microcontroller

- 16x2 I2C LCD display

- 5 LEDs

- 5 LDR resistors

- momentary switch

- and 10 resistors

LDR resistors have a resistance of about 2 kiloohms in normal lighting and about 300 ohms when illuminated with a laser pointer. Consequently, the resistors connected to them should have a resistance in the range of 680 ohms, up to 1.2 kiloohms. Depending on the type of LDR resistors used, this value may vary. Otherwise, for this project, it is best to make a custom PCB on which the Arduino and all the resistors and components will be mounted, so we will have greater visibility in case there is a need for any intervention. For that purpose, you can visit my sponsor PCBgogo. They offer 24 hours expedited service. Make your PCB on the link in the description.

Immediately after switching on, all LEDs start flashing and together with the corresponding sounds mark the beginning of the game. The end of the game is also marked by flashing all the diodes, and the LCD display shows the result in the form of points. For a new game, you have to press the Start button.

Schematic.jpg
        /**
 * How to play:
 * Goal of the game is to shoot as many alien spaceships as possible.
 * At game start you have 5 shots. One of 5 red LEDs ("spaceship") lit randomly for a short
 * time and you have to shoot this spaceship as fast as possible. If you do not hit the
 * spaceship fast enough you loose and the game is over. After you hit the spaceship the
 * LED will go off. If you run out of shots the game is over, but for every successfully
 * hit spaceship you gain one more shot.
 */
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define PIN_PIEZO 6

#define AMOUNT_SPACESHIPS 5
#define AMOUNT_SHOTS_INIT 5

#define MAX_SPACESHIP_DELAY  2000 // in ms
#define MIN_SPACESHIP_DELAY   250 // in ms
#define SPACESHIP_DELAY_STEP  100 // in ms

#define TONE_SHOT  1
#define TONE_END_1 2
#define TONE_END_2 3

LiquidCrystal_I2C lcd(0x27,16,2);

bool gameRunning;
byte pinLEDs[AMOUNT_SPACESHIPS] = {9, 10, 11, 12, 13};
byte pinLDRs[AMOUNT_SPACESHIPS] = {2,  3,  4,  5, 7};
int activeSpaceship;
byte shots;
unsigned int spaceshipDelay;
unsigned int score;
unsigned long shipAppearance;

void setup()
{
  Serial.begin(9600);

  lcd.begin();
  lcd.setCursor(1,0);
  lcd.print(" Laser Shooter");
  lcd.setCursor(1,1);
  lcd.print("    mircemk");
  
  randomSeed(analogRead(0));
  pinMode(PIN_PIEZO, OUTPUT);
  for (byte i = 0; i < AMOUNT_SPACESHIPS; i++) {
    pinMode(pinLEDs[i], OUTPUT);
    pinMode(pinLDRs[i], INPUT);
    digitalWrite(pinLEDs[i], LOW);
  }

  spaceshipDelay = MAX_SPACESHIP_DELAY;
  gameRunning = true;
  activeSpaceship = -1;
  score = 0;
  shots = AMOUNT_SHOTS_INIT;
  initAnimation();
}

void loop()
{
  if (gameRunning) {
    updateSpaceships();
    checkShoot();
  }
}

void updateSpaceships()
{
  if (activeSpaceship > -1) {
    if ((millis() - shipAppearance) > spaceshipDelay) {
      endGame();
    }
    return;
  }

  // delay between two spaceships
  delay(random(500, 3000));

  activeSpaceship = random(0, AMOUNT_SPACESHIPS);
  digitalWrite(pinLEDs[activeSpaceship], HIGH);
  shipAppearance = millis();
  if (spaceshipDelay > (MIN_SPACESHIP_DELAY + SPACESHIP_DELAY_STEP)) {
    spaceshipDelay -= SPACESHIP_DELAY_STEP;
  }
}

void checkShoot()
{
  if (activeSpaceship == -1) {
    return;
  }
  for (byte i = 0; i < AMOUNT_SPACESHIPS; i++) {
    if (digitalRead(pinLDRs[i]) == HIGH) {
      continue;
    }

    shots--;
    if (activeSpaceship == i) {
      // player hit spaceship
      digitalWrite(pinLEDs[activeSpaceship], LOW);
      activeSpaceship = -1;
      score++;
      shots++;
      tone(PIN_PIEZO, 400, 50);
      return;
    }
    if (shots <= 0) {
      endGame();
      return;
    }
  }
}

void initAnimation()
{
  Serial.println("Incoming alien ships...");
  lcd.setCursor(1,0);
  lcd.print("Incoming ships  ");
  lcd.setCursor(1,1);
  lcd.print("  * * * * * *   ");
  for (byte i = 0; i < 9; i++) {
    for (byte j = 0; j < AMOUNT_SPACESHIPS; j++) {
      digitalWrite(pinLEDs[j], i%2);
    }
    delay(250);
     tone(PIN_PIEZO, 1220 - (i%2 * 50));
    delay(300);
    noTone(PIN_PIEZO);
  }
}

void endGame()
{
  gameRunning = false;
  Serial.println("GAME OVER");
    lcd.setCursor(1,0);
  lcd.print("  GAME OVER    ");
  lcd.setCursor(1,1);
  lcd.print("Final score:");
  lcd.print(score);
  Serial.println("Final score: " + String(score));
  
  for (byte i = 0; i < 6; i++) {
    for (byte j = 0; j < AMOUNT_SPACESHIPS; j++) {
      digitalWrite(pinLEDs[j], i%2);
    }
    tone(PIN_PIEZO, 660 - (i%2 * 50));
    delay(300);
    noTone(PIN_PIEZO);
  }
  for (byte i = 0; i < AMOUNT_SPACESHIPS; i++) {
    digitalWrite(pinLEDs[i], LOW);
  }
}
    
Mirko Pavleski
Electronics , Arduino , Physics

Categories