/*
Forum: https://forum.arduino.cc/t/hilfe-bei-meinem-dino-spiel/1195564
Wokwi: https://wokwi.com/projects/382919062988146689
Sehr weitgehend umgeschrieben auf eine einfache "State Machine"
mit
- Leveln, bei denen die Position des Hindernisses jeweils per Zufall neu gesetzt wird
und die Geschwindigkeit des ">" Zeichens zunimmt (nur bis Level 9)
-
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C-Display-Adresse und Zeilenzahl
const byte ROWS = 4; //three rows
const byte COLS = 3; //four columns
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 3, 2}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
struct position {
byte x;
byte y ;
};
position dino {1, 1};
position hindernis {10, 1};
char richtung;
byte schritteOben = 0;
constexpr byte erlaubterSprung = 2;
int level = 0;
int gameStarted = 0; //wird später zum starten auf 1 gesetzt
enum zustandsAuswahl {ANSAGE, DINOLAEUFT,PAUSE, GAMEOVER};
zustandsAuswahl zustand = ANSAGE;
unsigned long zuletztBewegt = 0;
unsigned long zeitProSchritt {550}; // Jede Sekunde ein Schritt
void setup() { //LCD Display initialisieren und "Startmenü" anzeigen
Serial.begin(115200);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Press 0 to start");
lcd.setCursor(0, 1);
lcd.print("FAKE DINO RUNNER");
Serial.println("Startschirm");
}
void loop() {
zustandsMaschine();
}
void zustandsMaschine() {
char key = keypad.getKey();
switch (zustand) {
case ANSAGE:
if (key == '0') {
startGame();
zustand = DINOLAEUFT;
}
break;
case DINOLAEUFT:
bewegeDino(key);
if (key == '5'){
zustand = PAUSE;
}
break;
case PAUSE:
if (key != NO_KEY) {
zustand = DINOLAEUFT;
}
break;
case GAMEOVER:
gameOver();
zustand = ANSAGE;
break;
}
}
void bewegeDino(char aKey) { // automatische Bewegung des ">" (Dinos) nach rechts Richtung Hinderniss "#"
if (aKey != NO_KEY) {
richtung = aKey;
}
if (millis() - zuletztBewegt >= zeitProSchritt) {
zuletztBewegt = millis();
lcd.setCursor(dino.x, dino.y);
lcd.print(" ");
if (richtung == '2') {
dino.y = 0;
richtung = NO_KEY;
}
if (richtung == '8') {
dino.y = 1;
richtung = NO_KEY;
schritteOben = 0;
}
if (schritteOben > erlaubterSprung) {
dino.y = 1;
schritteOben = 0;
}
dino.x++;
if (kollision()) {
zustand = GAMEOVER;
Serial.println("Game Over");
} else {
if (dino.x >= 16) {
dino.x = 1;
dino.y = 1;
setzeHindernis(true);
}
lcd.setCursor(dino.x, dino.y);
lcd.print(">");
if (dino.y == 0) {
schritteOben++;
}
}
}
}
boolean kollision() {
return (dino.x == hindernis.x && dino.y == hindernis.y);
}
void setzeHindernis(boolean loeschen) {
if (loeschen) {
lcd.setCursor(hindernis.x, hindernis.y);
lcd.print(" ");
}
hindernis.x = random(5, 16);
lcd.setCursor(hindernis.x, hindernis.y);
lcd.print("#");
level++;
if (level < 10) {
zeitProSchritt = 550 - level * 50;
}
Serial.print("Level : ");
Serial.println(level);
}
void startGame() { //">" und "#", Dino und Hindernis werden auf das Display geprintet
Serial.println("Dino läuft ..");
lcd.clear();
schritteOben = 0;
level = 0;
zeitProSchritt = 550;
dino.x = 1;
dino.y = 1;
lcd.setCursor(dino.x, dino.y);
lcd.print(">");
setzeHindernis(false);
}
void gameOver() { // GAME-OVER screen
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" GAME OVER");
lcd.setCursor(0, 1);
lcd.print("Restart with 0");
}
// Falls die Daten mal geprüft werden müssen ...
void printPos() {
Serial.print("dino.x ");
Serial.println(dino.x);
Serial.print("dino.y ");
Serial.println(dino.y);
Serial.print("hindernis.x ");
Serial.println(hindernis.x);
Serial.print("hindernis.y ");
Serial.println(hindernis.y);
}