Heißer Draht Spiel mp3 Dateien einbinden

Nabend,
ich muckel mal wieder so mit try und error.
Die Idee: das Spiel "Heißer Draht" oder "buzz wire" kennt ihr wohl. Jetzt habe ich ich eins gefunden und würde gerne zwei Sachen einbinden, komme aber nicht so auf die Idee.
Die Töne des Piezo Lautsprechers möchte ich ersetzen durch das abspielen von mp3 Dateien (den DFPlayer habe ich separat zum laufen bekommen).
Und eine Zeit (Startbeginn - Ende) könnte auch Klasse sein.
Hier der sketch von dem Spiel welches mir gefällt:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//use this include instead when not using an I2C display
//#include <LiquidCrystal.h>
#include "pitches.h"

// use a 20 chars and 4 line display
// some of the lcd cursor/print statements will have to be adjusted to fit on a 16x2 screen
const int lcdColumns = 20;
const int lcdRows = 4;

// set the LCD address to 0x27
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);

// use the following lines instead when not using an I2C display:
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
//const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
//LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// the hook the player uses to play the game is connected to the GND pin
// the pin that the start point is attached to
const int startPin = 8;
// the pin that the end point is attached to
const int endPin = 9;
// the pin that the wire is attached to
const int wirePin = 10;
// the pin that the speaker is attached to
const int speakerPin = 7;

// total number of levels
const int noLevels = 2; //9
// number of lives in level 1 (each next level has 1 life less)
const int livesLevel1 = 5; // 9

// custom character for a heart
byte heart[8] = {
  B00000,
  B01010,
  B11111,
  B11111,
  B01110,
  B00100,
  B00000,
  B00000,
};

// custom character for a lost heart
byte heartEmpty[8] = {
  B00000,
  B01010,
  B10101,
  B10001,
  B01010,
  B00100,
  B00000,
  B00000,
};

// custom character for a medal
byte medal[8] = {
  B11111,
  B10001,
  B10001,
  B01010,
  B01110,
  B11111,
  B11111,
  B01110,
};


// setup function
void setup()
{
  // set the start, end and wire pins to input with an internal pull-up mode
  pinMode(startPin, INPUT_PULLUP);
  pinMode(endPin, INPUT_PULLUP);
  pinMode(wirePin, INPUT_PULLUP);

  // set the speaker pin to output mode
  pinMode(speakerPin, OUTPUT);  

  // initialize the LCD display
  // skip the next line when not using an I2C display
  lcd.init();
  
  // enable the LCD backlight
  // skip the next line when not using an I2C display
  lcd.backlight();

  // set the number of columns and rows in the LCD display
  lcd.begin(lcdColumns, lcdRows);

  // create the custom characters
  lcd.createChar(1, heart);
  lcd.createChar(2, heartEmpty);
  lcd.createChar(3, medal);

  // uncomment the next line to show a self test screen
  // selfTestLoop();
}

// main game loop
void loop()
{
  // variable to keep track if we lost the game or not
  bool gameOver = false;

  // print the welcome message
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Buzz Wire Deluxe");
  delay(2000);

  // total number of lives within a level
  int totalLives;
  // lives left within a level
  int currentLives;

  // loop over the levels
  for (int level = 1 ; level <= noLevels ; level++) {
    // each next level starts with 1 less lives
    totalLives = livesLevel1 - level + 1;
    currentLives = totalLives;

    // print the level start message
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Level ");
    lcd.print(level);
    lcd.setCursor(0, 1);
    lcd.print("Touch start to begin");

    // wait until start is touched
    while (!isStartTouched()) {
    }

    // print get ready
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Get ready... ");

    // play the level start melody
    melodyLevelStart();

    // print go! and wait a second
    lcd.print("GO!");
    delay(1000);

    // clear the screen, print the level number and initial lives
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Level ");
    lcd.print(level);
    printLives(currentLives, totalLives);

    // level loop, repeat until level completed or no lives left
    do {
      bool wireTouched = false;
      bool endTouched = false;

      // wait for the wire or end to be touched
      do {
        wireTouched = isWireTouched();
        endTouched = isEndTouched();
      } while (!wireTouched && !endTouched);

      if (wireTouched) {
        // wire was touched, reduce lives and continue
        currentLives--;
      } else {
        // end touched, break the level loop
        break;
      }

      // update the lives on the display
      printLives(currentLives, totalLives);

      // play the wire touched melody
      melodyLevelWireTouched();
    } while (currentLives > 0);

    if (currentLives > 0) {
      // level was completed with at least 1 life
      // print a level finished message
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Level finished!!!");
      // play the level finished melody
      melodyLevelFinished();
      // wait 3 seconds
      delay(3000);
    } else {
      // level was ended because lives dropped to 0, game over! break the levels loop
      break;
    }
  
  }

  // levels loop was ended, check why
  if (currentLives == 0) {
    // levels loop was ended because of a game over
    // print game over message
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Game over!!!");
    // play the game over melody
    melodyLevelGameOver();
  } else {
    // all levels completed
    // print a champion message
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("\x03\x03 Champion \x03\x03");
    // play the champion melody
    melodyChampion();
  }

  // wait 3 seconds
  delay(3000);

  // show a touch start to begin message
  lcd.setCursor(0, 1);
  lcd.print("Touch start to begin");
  // wait for start to be touched
  while (!isStartTouched()) {
  }

}

// print the number of lives
void printLives(int currentLives, int totalLives) {
  lcd.setCursor(0, 1);
  lcd.print("Lives ");
  for (int i = 1 ; i <= totalLives ; i++) {
    if (i <= currentLives) {
      lcd.print("\1");
    } else {
      lcd.print("\2");
    }
  }
}

// test if the wire is being touched
bool isWireTouched() {
  return !digitalRead(wirePin);
}

// test if the start is being touched
bool isStartTouched() {
  return !digitalRead(startPin);
}

// test if the end is being touched
bool isEndTouched() {
  return !digitalRead(endPin);
}


// play the level start melody
void melodyLevelStart() {
  tone(speakerPin, NOTE_C4, 200);
  delay(600);
  tone(speakerPin, NOTE_C4, 200);
  delay(600);
  tone(speakerPin, NOTE_C4, 200);
  delay(600);
  tone(speakerPin, NOTE_C5);
  delay(600);
  noTone(speakerPin);
}

// play the level finished melody
void melodyLevelFinished() {
  tone(speakerPin, NOTE_C4);
  delay(300);
  tone(speakerPin, NOTE_D4);
  delay(300);
  tone(speakerPin, NOTE_E4);
  delay(300);
  tone(speakerPin, NOTE_F4);
  delay(300);
  tone(speakerPin, NOTE_G4);
  delay(300);
  noTone(speakerPin);
}

// play the wire touched melody
void melodyLevelWireTouched() {
  tone(speakerPin, NOTE_A4);
  delay(300);
  tone(speakerPin, NOTE_GS4);
  delay(300);
  tone(speakerPin, NOTE_G4);
  delay(1000);
  noTone(speakerPin);
}

// play the game over melody
void melodyLevelGameOver() {
  tone(speakerPin, NOTE_A4);
  delay(300);
  tone(speakerPin, NOTE_GS4);
  delay(300);
  tone(speakerPin, NOTE_G4);
  delay(300);
  tone(speakerPin, NOTE_FS4);
  delay(300);
  tone(speakerPin, NOTE_F4);
  delay(300);
  tone(speakerPin, NOTE_E4);
  delay(300);
  tone(speakerPin, NOTE_DS4);
  delay(300);
  tone(speakerPin, NOTE_D4);
  delay(300);
  tone(speakerPin, NOTE_CS4);
  delay(300);
  tone(speakerPin, NOTE_C4);
  delay(1000);
  noTone(speakerPin);
}

// play the champion melody
void melodyChampion() {
  tone(speakerPin, NOTE_C4);
  delay(300);
  tone(speakerPin, NOTE_D4);
  delay(300);
  tone(speakerPin, NOTE_E4);
  delay(300);
  tone(speakerPin, NOTE_F4);
  delay(300);
  tone(speakerPin, NOTE_G4);
  delay(300);
  tone(speakerPin, NOTE_A4);
  delay(300);
  tone(speakerPin, NOTE_B4);
  delay(300);
  tone(speakerPin, NOTE_C5);
  delay(300);
  tone(speakerPin, NOTE_B4);
  delay(300);
  tone(speakerPin, NOTE_A4);
  delay(300);
  tone(speakerPin, NOTE_G4);
  delay(300);
  tone(speakerPin, NOTE_F4);
  delay(300);
  tone(speakerPin, NOTE_E4);
  delay(300);
  tone(speakerPin, NOTE_D4);
  delay(300);
  tone(speakerPin, NOTE_C4);
  delay(1000);
  noTone(speakerPin);
}

// run a self test loop, useful to test if the display and pins are hooked up correctly
void selfTestLoop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("\x01\x02\x03");
  while(true) {
    lcd.setCursor(0, 1);
    lcd.print("wire  : ");
    lcd.print(isWireTouched() ? "yes" : "no ");
    lcd.setCursor(0, 2);
    lcd.print("start : ");
    lcd.print(isStartTouched() ? "yes" : "no ");
    lcd.setCursor(0, 3);
    lcd.print("end   : ");
    lcd.print(isEndTouched() ? "yes" : "no ");
  }
}

Ich Antworte mir mal kurz selbst.
Ich meine, dass ich hier im Ansatz richtig bin.

// play the champion melody
void melodyChampion()

also void melodyChampion tauschen gegen:
myDFPlayer.play(1); //Spielt die erste Datei

Oder liege ich da ganz falsch?

Achso, danke für euer Interesse

Grüße Uwe

Danke, ich versuche jetzt erstmal die Ausgabe mit dem Piezo rauszunehmen.
Leider gibt es da ein Problem was ich nicht verstehe:
Nehme ich die "MelodyLevelWireTouched" raus. Geht das Spiel sofort auf "Game over" wenn ich den Draht berühre. Es sollte ja eigentlich erstmal eins von dem "Leben" abgezogen werden.
Ich komme da nicht weiter.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "pitches.h"
const int lcdColumns = 20;
const int lcdRows = 4;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
const int startPin = 8;
const int speakerPin = 7;
const int endPin = 9;
const int wirePin = 10;
const int noLevels = 2; //9
const int livesLevel1 = 5; // 9

// custom character for a heart
byte heart[8] = {
  B00000,
  B01010,
  B11111,
  B11111,
  B01110,
  B00100,
  B00000,
  B00000,
};

// custom character for a lost heart
byte heartEmpty[8] = {
  B00000,
  B01010,
  B10101,
  B10001,
  B01010,
  B00100,
  B00000,
  B00000,
};

// custom character for a medal
byte medal[8] = {
  B11111,
  B10001,
  B10001,
  B01010,
  B01110,
  B11111,
  B11111,
  B01110,
};

// setup function
void setup()
{
  // set the start, end and wire pins to input with an internal pull-up mode
  pinMode(startPin, INPUT_PULLUP);
  pinMode(endPin, INPUT_PULLUP);
  pinMode(wirePin, INPUT_PULLUP);
  lcd.init();
  lcd.backlight();


  // set the number of columns and rows in the LCD display
  lcd.begin(lcdColumns, lcdRows);

  // create the custom characters
  lcd.createChar(1, heart);
  lcd.createChar(2, heartEmpty);
  lcd.createChar(3, medal);

}

void loop()
{
  // variable to keep track if we lost the game or not
  bool gameOver = false;

  // print the welcome message
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Buzz Wire Deluxe");
  delay(2000);

  // total number of lives within a level
  int totalLives;
  // lives left within a level
  int currentLives;

  // loop over the levels
  for (int level = 1 ; level <= noLevels ; level++) {
    // each next level starts with 1 less lives
    totalLives = livesLevel1 - level + 1;
    currentLives = totalLives;

    // print the level start message
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Level ");
    lcd.print(level);
    lcd.setCursor(0, 1);
    lcd.print("Touch start to begin");

    // wait until start is touched
    while (!isStartTouched()) {
    }



    // print get ready
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Get ready... ");

    
    // print go! and wait a second
    lcd.print("GO!");
    delay(1000);

    // clear the screen, print the level number and initial lives
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Level ");
    lcd.print(level);
    printLives(currentLives, totalLives);

    // level loop, repeat until level completed or no lives left
    do {
      bool wireTouched = false;
      bool endTouched = false;

      // wait for the wire or end to be touched
      do {
        wireTouched = isWireTouched();
        endTouched = isEndTouched();
      } while (!wireTouched && !endTouched);

      if (wireTouched) {
        // wire was touched, reduce lives and continue
        currentLives--;
      } else {
        // end touched, break the level loop
        break;
      }
      // update the lives on the display
      printLives(currentLives, totalLives);

      // play the wire touched melody
            
     // melodyLevelWireTouched();

      
    } while (currentLives > 0);

    if (currentLives > 0) {
      // level was completed with at least 1 life
      // print a level finished message
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Level finished!!!");
            
      // wait 3 seconds
      delay(3000);
    } else {
      // level was ended because lives dropped to 0, game over! break the levels loop
      break;
    }
  
  }

  // levels loop was ended, check why
  if (currentLives == 0) {
    // levels loop was ended because of a game over
    // print game over message
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Game over!!!");
        
  } else {
    // all levels completed
    // print a champion message
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("\x03\x03 Champion \x03\x03");
      }

  // wait 3 seconds
  delay(3000);

  // show a touch start to begin message
  lcd.setCursor(0, 1);
  lcd.print("Touch start to begin");
  // wait for start to be touched
   while (!isStartTouched()) {
  }

}

// print the number of lives
void printLives(int currentLives, int totalLives) {
  lcd.setCursor(0, 1);
  lcd.print("Lives ");
  for (int i = 1 ; i <= totalLives ; i++) {
    if (i <= currentLives) {
      lcd.print("\1");
    } else {
      lcd.print("\2");
    }
  }
}

// test if the wire is being touched
bool isWireTouched() {
  return !digitalRead(wirePin);
}

// test if the start is being touched
bool isStartTouched() {
  return !digitalRead(startPin);
}

// test if the end is being touched
bool isEndTouched() {
return !digitalRead(endPin);
}


// play the wire touched melody
  void melodyLevelWireTouched() {
//  tone(speakerPin, NOTE_A4);
//  delay(300);
//  tone(speakerPin, NOTE_GS4);
//  delay(300);
  tone(speakerPin, NOTE_G4);
  delay(1000);
  noTone(speakerPin);
 }

Naja, wenn die Pause fehlt, in der die Melodie gespielt wird (1,6Sek) und in der man ja Zeit hat, den Draht wieder zu verlassen, zählt er die Leben schneller runter als du reagieren kannst. Nimm nur die Töne raus, aber lass die delays als Platzhalter für die Soundlänge vorerst (!) drin.

Danke,
das mit der Pause war ein guter Fingerzeig,
ich habe das nun so gelöst indem ich ein delay von 500 eingefügt habe.

printLives(currentLives, totalLives);
      delay (500);
      // play the wire touched melody

Nun kann ich mich der Einbindung des DF Player widmen. Der Ton für das berühren der Leitung ist ein Pferdewiehern, die Frau hat jetzt schon eine Krise. Immer wenn sie in das Bastelzimmer kommt sind Pferd und Schwein schon da. :grin:

Genauso muss das! :joy:
..und jetzt noch das Gockelkrähen für den Zielkontakt und du kannst die Koffer packen! :sweat_smile:

So, ich habe soweit fertig. Die Sounddateien werden zu meiner Zufriedenheit an den entsprechenden Stellen abgespielt, eine Stoppuhr habe ich auch beigefügt, wobei diese über den letzten "Start" Befehl gestartet wird, hat jetzt jemand mehrere Level geschafft, so wir auch nur die Zeit des letzten Level ausgegeben. Da muss ich noch tüfteln. Jetzt reicht es erstmal und ich muss die "hardware" zusammenbauen. Ich zeig dann mal ein fertiges Bild.
Danke für die Unterstützung.