mgbig
Published © GPL3+

Fast IR Game with Any Remote Control

Play a game on an LCD display with any remote control you want. But watch it, it gets faster in every level.

BeginnerShowcase (no instructions)6,052
Fast IR Game with Any Remote Control

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
It also worked with an UNO
×1
Standard LCD - 16x2 White on Blue
Adafruit Standard LCD - 16x2 White on Blue
with I2C connection
×1
IR receiver (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×11
Any Remote Control
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Sheamtic for Fast IR game

I did not find an LCD with I2C board (LCD 1602 + I2C HD44780 Modul). So I just made a shematic. My IR Diode (VS1838B LIRC) is connected like in this sheme, but make shure you make the right connection!! (Data: orange, GND: black, VCC: red). You can use an Arduino Nano or Uno.

Code

Code for Arduino IDE

Arduino
For the code you need the libraries for the IR sensor and the LCD display. For the IR sensor you also need the Wire.h library. Just copy the code, paste it to the Arduino IDE and upload it to the board.
/*
 Fast IR Game by mgbig V1.0
 */
#include <IRremote.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

char up = 3;
char down = 1;
char ok = 2;

// Define 3 characters for the LCD Display
byte up1[8] = {
  B00100,
  B01110,
  B10101,
  B00100,
  B00100,
  B00100,
  B00100,
  B00100
};

byte down1[8] = {
  B00100,
  B00100,
  B00100,
  B00100,
  B00100,
  B10101,
  B01110,
  B00100
};

byte ok1[8] = {
  B01110,
  B01010,
  B01110,
  B10000,
  B10100,
  B11000,
  B10100,
  B10010
};

int RECV_PIN = 11;  // IR Sensor on Pin 11

char* howtoplay[23] = {
  "> FAST IR GAME <",
  "   Press key    ",
  "You have to",      // if you don't want this howToPlay you can delete from here ...
  "press the key,",
  "that you see on",
  "the screen, when",
  "it is beetween",
  "the fences (#).",
  "It ist getting",
  "faster and there",
  "will be symbols",
  "that you do not",
  "have to hit!",
  "Try to get to",
  "Level 10 and win",
  "the game. Before",
  "you start, you",
  "have to define",
  "the keys on your",
  "remote control",
  "to play the game", // ... until here. Leave the last lines for propper work!
  "  Have fun !!",
  ""
};

String keyNames[] = {"up", "down", "right", "left", "ok", "+", "-", "#", "*"};
String keySymb[] = {"", "", "", "", "", "", "", "", ""};
long keys[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int keycount = 7;

int lev;
int xpos = 1;
int xadd = 1;
int xleft;
int xright;
int xstart = 0;
int xend = 15;

int actSym = 0;
int score;   // All together score
int scorePerLev; // Symbols in actual level
int scoreNextLev = 50;  // Symbols until next level

int gameState = -1;

bool pressed = false;

IRrecv irrecv(RECV_PIN);
decode_results results;

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  Serial.begin(9600);
  lcd.init();  // initialize the lcd
  lcd.backlight();
  lcd.createChar(up, up1);
  lcd.createChar(down, down1);
  lcd.createChar(ok, ok1);
  keySymb[0] = "\3";
  keySymb[1] = "\1";
  keySymb[2] = "\176";
  keySymb[3] = "\177";
  keySymb[4] = "\2";
  keySymb[5] = "+";
  keySymb[6] = "-";
  keySymb[7] = "#";
  keySymb[8] = "*";

  irrecv.enableIRIn(); // Start the receiver
  
  info(); //howtoplay show once at the start, can be removed when you know how to play
  randomSeed(analogRead(1));
}


void loop()
{

  // define keys only once
  // gameState= -1
  // ################################
  if (gameState == -1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Define Keys to");
    lcd.setCursor(0, 1);
    lcd.print("play the game...");
    delay(3000);
    pressed = false;
    for (int i = 0; i < keycount; i++) { // 0 und 5
      pressed = false;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Key for:");
      lcd.print(keyNames[i]);
      while (pressed != true) {
        if (irrecv.decode(&results)) {
          keys[i] = results.value;
          lcd.setCursor(0, 1);
          lcd.print(" ok!");
          Serial.println(keys[i]);
          delay(500);
          irrecv.resume(); // Receive the next value
          pressed = true;
        }
      }
      pressed = false;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Repaet key!");
      lcd.print(keyNames[i]);
      irrecv.resume();
      while (pressed != true) {
        if (irrecv.decode(&results)) {
          if (keys[i] == results.value) {
            lcd.setCursor(0, 1);
            lcd.print("is the same!");
            delay(500);
            pressed = true;
          } else {
            lcd.setCursor(0, 1);
            lcd.print("wrong!");
            delay(500);
            lcd.setCursor(0, 1);
            lcd.print("       ");
          }
          irrecv.resume();
        }
      }
    }
    gameState = 0;  // ok to select level
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Keys done!");
    delay(2000);
  }

  // Select Level
  // gameState=0
  //###########################
  if (gameState == 0) {
    lev = 1;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Select Level+ok");
    lcd.setCursor(0, 1);
    lcd.print("Level: ");
    lcd.print(lev);
    irrecv.resume();
    pressed = false;
    Serial.println("Level");
    Serial.println(pressed);
    while (pressed != true) {
      if (irrecv.decode(&results)) {
        Serial.println(results.value);
        if (results.value == keys[0]) lev++;
        if (results.value == keys[1]) lev--;
        if (results.value == keys[4]) pressed = true;
        if (lev < 1) lev = 1;
        if (lev > 10) lev = 10;
        lcd.setCursor(7, 1);
        lcd.print(lev);
        lcd.print(" ");
        irrecv.resume();
      }
      delay(250);
    }
    lcd.setCursor(0, 0);
    lcd.print("Ok! Play in    ");
    delay(2000);
    lcd.clear();
    gameState = 1; // Main gameplay
    score = 0;
    scorePerLev = 0;
    keycount = 7;
    xleft = 4;
    xright = 11;
    drawField("");
    irrecv.resume();
    Serial.println("Level Set");
  }

  // Main Game
  // gameState=1
  //###############################
  if (gameState == 1) {
    xpos = 0;
    xadd = 1;
    int k = 0;
    bool rightkey = false;
    pressed = false;
    actSym = floor(random(0, keycount));
    while (pressed != true) {
      Serial.println(xpos);
      if (irrecv.decode(&results)) {
        for (int i = 0; i < keycount; i++) {
          if (results.value == keys[i]) {
            rightkey = true;
            k = i;
          }
        }
        if (rightkey == true) {
          scorePerLev++;
          if (xpos <= xleft || xpos >= xright) {
            score = score - (4 + lev);
            // negativ sound
          }
          if (actSym == k) {
            lcd.setCursor(xpos, 1);
            lcd.print(" ");
            score++;
            drawField("");
            changeDirection();
          } else {
            score = score - (2 + lev);
            drawField(" :(   ");
            // negativ sound
          }
          actSym = floor(random(0, keycount));
          rightkey = false;
        }
        delay(10);
        irrecv.resume();
        if (scorePerLev == scoreNextLev) {
          scorePerLev = 0;
          lev++;
          drawField("");
          if (lev < 11) {
            lcd.setCursor(0, 1);
            lcd.print("Next level!");
            waitForOK();
            // Check for score and display message here later
            lcd.setCursor(0, 1);
            lcd.print("           ");
          } else {
            gameState = 5;
            pressed = true;
          }
        }
      }
      lcd.setCursor(xpos, 1);
      lcd.print(" ");
      xpos = xpos + xadd;
      if (xpos == xend + 1 || xpos == xstart - 1) {
        if (actSym < 7) {
          score = score - (2 * (lev + 5));
          drawField(" :(   ");
        } else {
          drawField("");
        }
        changeDirection();
        actSym = floor(random(0, keycount));
        // negativ sound
      }
      lcd.setCursor(xpos, 1);
      lcd.print(keySymb[actSym]);
      delay(200 - (lev * 10));
      if (score < 0) {
        gameState = 9;
        pressed = true;
      }
    } // Main Game loop End

  }

  // Win
  // ##################
  if (gameState == 5) {
    // positiv sound
    lcd.setCursor(0, 1);
    lcd.print("You win the Game");
    lcd.setCursor(0, 0);
    lcd.print("Bravo! ");
    waitForOK();
    gameState = 0;
  }

  // Game Over
  // ##################
  if (gameState == 9) {
    // negativ sound
    for (int i = 0; i < 5; i++) {
      lcd.setCursor(0, 1);
      lcd.print("                ");
      delay(200);
      lcd.setCursor(0, 1);
      lcd.print("   Game over!   ");
      delay(300);
    }
    waitForOK();
    gameState = 0;
  }

}

void info () {
  int i = 0;
  while (howtoplay[i] != "") {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(howtoplay[i]);
    lcd.setCursor(0, 1);
    lcd.print(howtoplay[i + 1]);
    delay(300);
    waitForKey();
    i++;
  }
  irrecv.resume();
}

void drawField(String empty) {
  Serial.println("drawField");
  int SCur;
  if (empty == "") empty = "      ";
  lcd.setCursor(0, 0);
  lcd.print("################");
  if (lev > 3) {
    xleft = floor(random(4, 7));
    xright = xleft + 7;
    if (lev > 6) xright = xleft + 6;
    if (lev > 9) xright = xleft + 5;
  }
  if (lev > 4) keycount = 8;
  if (lev > 6) keycount = 9;
  lcd.setCursor(xleft + 1, 0);
  lcd.print(empty.substring(0, xright - xleft - 1));
  lcd.setCursor(0, 0);
  lcd.print("L");
  lcd.print(lev);
  if (score < 1000) SCur = 13;
  if (score < 100) SCur = 14;
  if (score < 10) SCur = 15;
  if (score < 0) SCur = 14;
  lcd.setCursor(SCur, 0);
  lcd.print(score);
}

void changeDirection() {
  xpos = xstart;
  xadd = 1;
  if (lev > 3) {
    int dir = floor(random(0, 2));
    if (dir == 1) {
      xpos = xend;
      xadd = -1;
    }
  }
}

void waitForKey () {
  bool press = false;
  irrecv.resume();
  while (press == false) {
    if (irrecv.decode(&results)) {
      if (results.value != 0) press = true;
      irrecv.resume();
      delay(200);
    }
  }
}

void waitForOK()  {
  delay(1000);
  bool press = false;
  irrecv.resume();
  while (press == false) {
    if (irrecv.decode(&results)) {
      if (results.value == keys[4]) press = true;
      irrecv.resume();
      delay(200);
    }
  }
}

Credits

mgbig
0 projects • 4 followers

Comments