#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <vector>
#define TFT_DC 27 // Pin für die Daten/Command-Auswahl des Displays (2) bei normal
#define TFT_CS 12 // Chip-Select-Pins des Displays (15) bei normal
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); // Initialisierung des Displays
#define SpielfeldX 200
#define SpielfeldY 200
#define Feldgroesse 10
#define VERT_PIN 34
#define HORZ_PIN 35
#define SEL_PIN 0
bool Spielstart = false;
// Definition einer Struktur für die Koordinaten einer Schlange
struct SchlangenKoord {
int x;
int y;
};
// Definition einer Struktur für die Koordinaten einer Frucht
struct FruchtKoord {
int x;
int y;
} frucht;
SchlangenKoord Richtung = {1, 0}; // Initialisierung der Bewegungsrichtung der Schlange (rechts)
// Deklaration eines Vektors, der Punkte enthält, um die Segmente der Schlange zu speichern
std::vector<SchlangenKoord> snake;
bool FruchtSchlangeCheck(int x, int y) {
for (auto &segment : snake) {
if (segment.x == x && segment.y == y) {
return true;
}
}
return false;
}
void SchlangenBewegung() {
// Neue Kopfposition berechnen
SchlangenKoord Kopfposition = {snake[0].x + Richtung.x, snake[0].y + Richtung.y}; //Richtung X & Y
// Prüfen, ob die neue Kopfposition innerhalb des Spielfelds liegt und nicht mit der Schlange kollidiert
if (Kopfposition.x >= 2 && Kopfposition.x < 22 && //Border
Kopfposition.y >= 6 && Kopfposition.y < 26) {
// Kollision mit der Schlange überprüfen
for (auto &segment : snake) {
if (Kopfposition.x == segment.x && Kopfposition.y == segment.y) {
Spielstart = false;
return; // Kollision gefunden, Bewegung stoppen
}
}
// Schlange am neuen Kopf zeichnen
tft.fillRect(Kopfposition.x * Feldgroesse, Kopfposition.y * Feldgroesse, Feldgroesse, Feldgroesse, ILI9341_WHITE);
// Schlange bewegen
snake.insert(snake.begin(), Kopfposition); // Neuen Kopf hinzufügen
if (Kopfposition.x == frucht.x && Kopfposition.y == frucht.y) {
// Wenn der Kopf auf eine Frucht trifft, frucht neu platzieren
Frucht();
} else {
// Letztes Segment entfernen und löschen
auto &lastSegment = snake.back();
tft.fillRect(lastSegment.x * Feldgroesse, lastSegment.y * Feldgroesse, Feldgroesse, Feldgroesse, ILI9341_BLACK);
snake.pop_back();
}
SpielfeldZeichnung();
}
else{Spielstart = false;}
}
void SchlangeBild() {
// Zeichnen der Schlange
for (SchlangenKoord &Teil : snake) {
tft.fillRect(Teil.x * Feldgroesse, Teil.y * Feldgroesse, Feldgroesse, Feldgroesse, ILI9341_WHITE);
}
}
void Frucht() {
do {
frucht.x = random(2, 22);
frucht.y = random(6, 26);
} while (FruchtSchlangeCheck(frucht.x, frucht.y)); // Wiederholen bis gültige Position gefunden ist
tft.fillRect(frucht.x * Feldgroesse, frucht.y * Feldgroesse, Feldgroesse, Feldgroesse, ILI9341_RED); // Zeichnen der Frucht auf dem Display
}
void Joystick() {
int vert = analogRead(VERT_PIN);
int horz = analogRead(HORZ_PIN);
if (vert < 2048 && Richtung.y != -1) {
Richtung = {0, 1}; // Nach unten
}
if (vert > 2048 && Richtung.y != 1) {
Richtung = {0, -1}; // Nach oben
}
if (horz < 2048 && Richtung.x != -1) {
Richtung = {1, 0}; // Nach rechts
}
if (horz > 2048 && Richtung.x != 1) {
Richtung = {-1, 0}; // Nach links
}
}
void Neustart() {
snake.clear();
snake.push_back({8, 16});
snake.push_back({7, 16});
snake.push_back({6, 16});
Richtung = {1,0};
Frucht();
while (!Spielstart) {
int vert = analogRead(VERT_PIN);
int horz = analogRead(HORZ_PIN);
SchlangeBild();
if (vert < 2048 || vert > 2048 || horz < 2048 || horz > 2048) {
Spielstart = true;
}
}
}
void SpielfeldZeichnung(){
tft.drawRect(20-1, 60-1, SpielfeldX+1, SpielfeldY+1, ILI9341_WHITE); // Zeichnen des Spielfeldrahmens
}
void setup() {
tft.begin(); // Initialisierung des Displays
SpielfeldZeichnung();
tft.setCursor(1, 3);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.println("Druecke eine beliebige Taste um das Spiel zu starten");
snake.push_back({8, 16});
snake.push_back({7, 16});
snake.push_back({6, 16});
pinMode(VERT_PIN, INPUT);
pinMode(HORZ_PIN, INPUT);
pinMode(SEL_PIN, INPUT_PULLUP);
Neustart();
}
void loop() {
if (Spielstart) {
SchlangenBewegung();
Joystick();
delay(100);
}
else{
tft.fillScreen(ILI9341_BLACK);
SpielfeldZeichnung();
tft.setCursor(1, 3);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.println("Druecke eine beliebige Taste um das Spiel zu starten");
Neustart();
}
}
//Buzzer - an GND + an PIN