Laby­rinth­spiel mit Joy­stick und TFT

Lese­zeit: 8 Minu­ten
Navi­ga­ti­on

Der Joy­stick besteht aus zwei Poten­tio­me­tern, jeweils einer für die X-Achse und einer für die Y-Achse. Bei­de lesen bei den Bewe­gun­gen die Span­nung und lie­fern dem Ardui­no jeweils einen ana­lo­gen Wert, der zwi­schen 0 und 1023 liegt.

Die Wer­te kön­nen je nach Joy­stick leicht nach oben oder unten abwei­chen. Die Beschrif­tung und die Rei­hen­fol­ge der Pins kön­nen sich je nach Joy­stick unter­schei­den.

Ach­seBezeich­nungAnschluss
X-AchseVRx/VERA0
Y-AchseVRy/HORA1
But­tonSW/SEL7

Das ver­wen­de­te TFT-Modul hat eine Bild­schirm­dia­go­na­le von 1,77 Zoll und eine Bild­schirm­auf­lö­sung von 160×128 Pixeln. Es wird über den ➨SPI-Bus ange­steu­ert.

Die Beschrif­tung und die Rei­hen­fol­ge der Pins kön­nen sich je nach ver­wen­de­ten TFT-Modul unter­schei­den.

Benö­tig­te Bau­tei­le:

  • Joy­stick
  • TFT-Modul 1,77 Zoll

Baue die Schal­tung auf.
(Fah­re mit der Maus über das Bild, um die Bezeich­nun­gen der Bau­tei­le zu sehen)

Es ste­hen meh­re­re Biblio­the­ken zur Aus­wahl, die sich aber in der Anwen­dung nicht unter­schei­den. Der Ein­fach­heit hal­ber wird die ein­ge­bau­te Biblio­thek TFT ver­wen­det.

Alter­na­tiv kannst du die Biblio­the­ken Adafruit_GFX und Adafruit_ST7735 instal­lie­ren.

Metho­de Anwei­sungPara­me­ter
TFT star­tenbegin();
Farb­sche­ma bestim­meninitR(initR(INITR_*TAB););BLACKTAB
GREENTAB
REDTAB
Bild­schirm aus­rich­tensetRotation(Richtung);Rich­tung = 0 → nicht dre­hen
Rich­tung = 1 → 90° dre­hen
Rich­tung = 2 → 180° dre­hen
Rich­tung = 3 → 270 ° dre­hen
Bild­schirm­hin­ter­grundfillScreen(Farbe);Bild­schirm­hin­ter­grund fül­len
Linie zeich­nendrawLine(StartX, Star­tY, EndeX, EndeY, Far­be);
hori­zon­ta­le Linie zeich­nendrawFastHLine(StartX, Star­tY, Län­ge, Far­be);
ver­ti­ka­le Linie zeich­nendrawFastVLine(StartX, Star­tY, Län­ge, Far­be);
Recht­eck zeich­nendrawRect(StartX, Star­tY,, Brei­te, Höhe, Far­be);
abge­run­de­tes Recht­eck zeich­nendrawRoundRect(StartX, Star­tY, Brei­te, Höhe, Ecken­ra­di­us, Far­be);
aus­ge­füll­tes Recht­eck zeich­nenfill.Rect(StartX, Star­tY, Brei­te, Höhe, Füll­far­be);
Kreis zeich­nendrawCircle(MittelpunkX, Mit­tel­punk­tY, Radi­us, Far­be);
Aus­ge­füll­ten Kreis zeich­nenfillCircle(MittelpunktX, Mit­tel­punk­tY, Radi­us, Füll­far­be);
Cur­sor set­zensetCursor(x, y);
Text­grö­ße set­zensetTextSize(Textgröße);Text­grö­ße:
1 - 4
Text­far­be bestim­mensetTextColor(Farbe);
Text schrei­benprint("Text"); println("Text");
Zei­len­um­bruchsetTextWrap(true/false);fal­se → Text fließt über den Rand des TFTs hin­aus
true → Text wird am Ende umge­bro­chen

Bei­spiel mit Gra­fik und Text

Defi­ni­ti­on der Far­ben: Du kannst sie ver­wen­den, um das Laby­rinth indi­vi­du­ell zu gestal­ten.

# define SCHWARZ  0x0000 // dezimal 0
# define BLAU     0x000F // dezimal 15
# define ROT      0xF800 // dezimal 406664
# define GRUEN    0x0E81 // dezimal 3713
# define CYAN     0x07FF // dezimal 2047
# define MAGENTA  0xF81F // dezimal 63519
# define GELB     0xFFE0 // dezimal 65504
# define WEISS    0xFFFF // dezimal 65535
# define BRAUN    0xFC00 // dezimal 64512
# define GRAU     0xF7F0 // dezimal 63472
Das Laby­rinth

Bin­de die benö­ti­gen Biblio­the­ken ein und defi­nie­re die Varia­blen. Beach­te die Kom­men­ta­re.

# include <TFT.h> 
# include <SPI.h>

// Zuordnung der Pins
int TFT_PIN_CS = 10;
int TFT_PIN_DC = 9;
int TFT_PIN_RST = 8;

// Name des TFTs definieren
TFT tft = TFT(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_RST);

/* 
  Farben als hexadezimal definiert
  alternativ:
  int SCHWARZ = 0;
  int BLAU = 15;
  . . . 
*/
# define SCHWARZ  0x0000 // dezimal 0
# define BLAU     0x000F // dezimal 15
# define ROT      0xF800 // dezimal 406664
# define GRUEN    0x0E81 // dezimal 3713
# define CYAN     0x07FF // dezimal 2047
# define MAGENTA  0xF81F // dezimal 63519
# define GELB     0xFFE0 // dezimal 65504
# define WEISS    0xFFFF // dezimal 65535
# define BRAUN    0xFC00 // dezimal 64512
# define GRAU     0xF7F0 // dezimal 63472

// Joystick analoge Pins
int XAchse = A0;
int YAchse = A1;

// Joystick Knopf
int JoystickButton = 7;

// Zustand des Buttons
int ButtonLesen;

// Spiel starten, nachdem der Knopf gedrückt wurde
bool SpielStart = false;

// Variablen für die Auswertung der Bewegung des Joysticks
int PositionX;
int PositionY;

// Bildschirm Höhe/Breite
const int Radius = 10;
const int BildschirmBreite = 160;
const int BildschirmHoehe = 128;

// Geschwindigkeit der Bewegung des Joysticks
// je höher, dest langsamer
const int Geschwindigkeit = 50;

// Bewegung des Kreises in Pixeln
const int Bewegung = 5;

// Startposition des Kreises
int CursorX = Radius;
int CursorY = BildschirmHoehe / 2;

// Variable für die Zeitmessung
long Start;

Wenn du die Adafruit-Bibliotheken ver­wen­den willst:

# include <SPI.h>
# include <Adafruit_GFX.h>
# include <Adafruit_ST7735.h>
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_RST);

Der setup-Teil:

void setup()
{
  pinMode(JoystickButton, INPUT_PULLUP);

  // Startbildschirm
  // schwarzes Farbschema horizontale Ausrichtung
  // Cursor setzen, Schriftgröße und -farbe definieren
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(1);
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(2);
  tft.setCursor(1, 10);
  tft.setTextColor(ROT);

  // ü -> \232
  tft.print("Start\nTaste dr\232cken");
}

Der loop-Teil. Beach­te die Kom­men­ta­re.

void loop()
{
  // Button/Knopf auswerten
  ButtonLesen = digitalRead(JoystickButton);
  if (ButtonLesen == LOW)
  {
    // Spiel wird gestartet
    SpielStart = true;

    // Parcours bauen
    ParcoursBauen();

    // Zeitmessung starten ➨millis()
    Start = millis();
  }

  // wenn der Button gedrückt wurde
  if (SpielStart)
  {
    // Bewegung der X-Achse lesen
    PositionX = analogRead(XAchse);
    // Bewegung X-Achse nach oben
    if (PositionX > 600)
    {
      // Kreis an der aktuellen Position "löschen"
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);

      // wenn der Bildschirmrand noch nicht erreicht wurde
      // vorwärts bewegen
      if (CursorX < BildschirmBreite) CursorX += Bewegung;
      tft.fillCircle(CursorX, CursorY, Radius, GELB);
      
      delay(Geschwindigkeit);
    }

    // Bewegung X-Achse nach unten
    if (PositionX < 300)
    {
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
      if (CursorX > Radius) CursorX -= Bewegung;
      tft.fillCircle(CursorX, CursorY, Radius, GELB);
      delay(Geschwindigkeit);
    }

    // Bewegung der Y-Achse lesen
    PositionY = analogRead(YAchse);

    // Bewegung Y-Achse nach rechts
    if (PositionY > 600)
    {
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
      if (CursorY < BildschirmHoehe - Radius) CursorY += Bewegung;
      tft.fillCircle(CursorX, CursorY, Radius, GELB);
      delay(Geschwindigkeit);
    }

    // Bewegung Y-Achse nach links
    if (PositionY < 300)
    {
      tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
      if (CursorY > Radius) CursorY -= Bewegung;
      tft.fillCircle(CursorX, CursorY, Radius, GELB);
      delay(Geschwindigkeit);
    }
     
    // unterer Bildschirmrand erreicht -> Spielende
    if (CursorX > BildschirmBreite - Radius)
    {
      ErgebnisZeigen();
    }
  }
}

Jetzt feh­len noch die Metho­den Ergeb­nis­Zei­gen() und Par­cours­Bau­en():

void ErgebnisZeigen()
{
  // Zeit berechnen
  int Sekunden;
  long VerstricheneZeit = millis() - Start;
  Sekunden = int(VerstricheneZeit / 1000);

  // Zeit anzeigen
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(2);
  tft.setCursor(1, 10);
  tft.setTextColor(ROT);
  tft.println(String(Sekunden) + " Sekunden\n\n");
  tft.println("Neustart\nTaste dr\232cken");
  SpielStart = false;

  // Startposition des Kreises zurücksetzen
  CursorX = Radius;
  CursorY = BildschirmHoehe / 2;
}

void ParcoursBauen()
{
  tft.fillScreen(SCHWARZ);

  // Kreis anzeigen
  tft.fillCircle(CursorX, CursorY, Radius, GELB);

  // Parcours "bauen"
  tft.fillRect(65, 35, 5, 45, BLAU);
  tft.fillRect(1, 1, 35, 35, BLAU);
  tft.fillRect(1, 80, 70, 70, BLAU);
  tft.fillRect(110, 1, 70, 95, BLAU);
}


Ver­wand­te Auf­ga­ben:


Letzte Aktualisierung: 20. Apr 2020 @ 7:46