#include <MD_MAX72xx.h>
#include <SPI.h>
#define MAX_DEVICES 2
const int maxX = MAX_DEVICES * 8 - 1;
const int maxY = 7;
#define MAX_INTENSITY 15 //
#include <LiquidCrystal_I2C.h>
#define melodyPin 9
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
#define Y_pin A0
#define X_pin A1
#define SW_pin 2
bool introState = false;
uint8_t menuLine;
uint8_t gameLevel = 1;
uint8_t rouletteLine = 1;
uint8_t space = 0;
uint8_t johnPorkSpace = 3;
MD_MAX72XX mx = MD_MAX72XX(MD_MAX72XX::PAROLA_HW, CS_PIN, MAX_DEVICES);
bool character[6] = { false, false, false, false, false, false }; // Johanna, Brigitte, Anette, Jochen, Manfred, Gustav
bool displayAdd[5] = { false, false, false, false, false };
uint8_t text1 = -1;
uint8_t text2 = 0;
uint8_t brightness = 15;
bool task = false;
bool game = false;
bool highscore = false;
bool leave = false;
bool roulette = false;
bool threeInARow = false;
bool crossUp = false;
bool onBlack = false;
bool onRed = false;
bool onGreen = false;
bool onNummber = false;
bool buttonXMoved = false;
bool buttonYMoved = false;
bool isButtonPressed = false;
int ringTone[] = {
392, 392, 392, 392,
392, 392, 262, 392,
392, 392, 440
};
uint8_t ringToneDuration[] = {
13, 13, 13, 13,
13, 13, 13, 13,
13, 13, 13
};
uint8_t goGamblingTone[] = {
123, 155, 220, 180
};
uint8_t goGamblingDuration[] = {
5, 5, 3, 4
};
const char* introWords[] = {
"JOHN PORK ",
"IS CALLING ",
"LET'S GO ",
"GAMBLING ",
"PRESS THE ",
"BUTTON TO ",
"INTERACT ",
"NOW TO GET ",
"TO THE MENU, ",
"PRESS THE ",
"BUTTON AND ",
"Scroll DOWN ",
"IN THE MENU, ",
"YOU SCROLL ",
"WITH THE ",
"BUTTON ",
"First We, ",
"gotta chose",
"a name ",
"selcet one: ",
" ",
" Welcome ",
" ",
"Lets get you",
" HOOKED!! ",
"You've just ",
"gotten a Task",
"LET'S GO ",
"GAMBLING ",
"You see the ",
"8 LED Right ?",
"They turn on ",
"right away ",
"and you bet ",
"where it'll ",
"DROP! ",
};
const char* people[6] = {
"Johanna ",
"Brigitte ",
"Anette ",
"Jochen ",
"Manfred ",
"Gustav ",
};
const char* menuWords[] = {
" LEVEL: ",
" PlAY A GAME;",
" HIGHSCORE: ",
" LEAVE!!!: ",
};
const char* tasksWords[] = {
" TASK: ",
"-Play a Game ",
"visit the HS:",
};
const char* gameLevelMenu[] = {
"The Roulette",
"3 in a Row ",
"Cross Up ",
};
const char* rouletteDropMenu[] = {
"On Black ",
"On Red ",
"On Green ",
"On Nummber ",
};
const byte JohnPorkUL[] = {
B00011,
B01110,
B10100,
B10101,
B10101,
B10100,
B00100,
B01000
};
const byte JohnPorkUR[] = {
B11000,
B01110,
B00101,
B10101,
B10101,
B00101,
B00100,
B00010
};
const byte JohnPorkLL[] = {
B01000,
B01000,
B10111,
B10101,
B10111,
B10000,
B01000,
B01111
};
const byte JohnPorkLR[] = {
B00010,
B00010,
B11101,
B10101,
B11101,
B00010,
B00010,
B11100
};
const byte FreakBobUL[] = {
B11111,
B10000,
B10111,
B10101,
B10111,
B10000,
B10100,
B10011
};
const byte FreakBobUR[] = {
B11111,
B00001,
B11101,
B10101,
B11101,
B00001,
B00101,
B11001
};
const byte FreakBobLL[] = {
B10001,
B10000,
B11111,
B10000,
B11111,
B00100,
B00100,
B00100
};
const byte FreakBobLR[] = {
B10001,
B00001,
B11111,
B00001,
B11111,
B00100,
B00100,
B00100
};
const byte taskFieldLow[] = {
B01111,
B10100,
B01111,
B10000,
B10000,
B11111,
B10000,
B10000
};
const byte taskFieldUp[] = {
B10001,
B01010,
B00100,
B11111,
B00000,
B10111,
B10101,
B11101
};
const byte emptyField[] = {
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000
};
void setup() {
mx.begin();
mx.control(MD_MAX72XX::INTENSITY, brightness);
mx.clear();
lcd.init();
lcd.backlight();
lcd.home();
Serial.begin(9600);
//John Pork Erstellen
lcd.createChar(0, JohnPorkUL);
lcd.createChar(1, JohnPorkUR);
lcd.createChar(2, JohnPorkLL);
lcd.createChar(3, JohnPorkLR);
//FreakBOB ertstellen
lcd.createChar(4, FreakBobUL);
lcd.createChar(5, FreakBobUR);
lcd.createChar(6, FreakBobLL);
lcd.createChar(7, FreakBobLR);
//Task Field
pinMode(melodyPin, OUTPUT);
pinMode(Y_pin, INPUT);
pinMode(X_pin, INPUT);
pinMode(SW_pin, INPUT_PULLUP);
}
void loop() {
if (!introState)
playIntro();
}
void displayText() {
text1++;
text2++;
lcd.clear();
lcd.setCursor(space, 0);
lcd.print(introWords[text1]);
lcd.setCursor(space, 1);
lcd.print(introWords[text2]);
if (displayAdd[0]) {
showJohnPork();
}
if (displayAdd[1]) {
showFreakBob();
}
if (displayAdd[2]) {
showTaskField();
}
if (displayAdd[3]) {
showEmptyField();
}
}
void updateText() {
text1++;
text2++;
}
void resetDisplayAdd() {
for (int i = 0; i < 5; i++) {
displayAdd[i] = false;
}
}
void playIntro() {
displayAdd[0] = true;
space = johnPorkSpace;
displayText();
while (!isButtonPressed) {
checkJoyStickState();
playMelody();
delay(500);
}
while (isButtonPressed) {checkJoyStickState();}
johnPorkIntro();
freakBobIntro();
nameChosing();
taskIntro();
introduceGame();
introState = true;
}
void introduceGame() {
resetDisplayAdd();
updateText();
displayAdd[0] = true;
space = johnPorkSpace;
displayText();
playLetsGoGambling();
while(isButtonPressed){checkJoyStickState();}
waitForRightButton();
gameMenu();
while (!(gameLevel == 1)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("not unlocked now");
lcd.setCursor(0, 1);
lcd.print("You return in 2 ");
delay(1000);
lcd.setCursor(14, 1);
lcd.print("1");
delay(1000);
gameMenu();
}
updateText();
displayText();
brightness = 15;
drawRoulette();
waitForLeftButton();
displayText();
waitForLeftButton();
displayText();
waitForLeftButton();
mx.clear();
rouletteMenu();
}
void rouletteMenu() {
waitForButton();
rouletteLine = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-");
lcd.setCursor(1, 0);
lcd.print(rouletteDropMenu[0]);
lcd.setCursor(1, 1);
lcd.print(rouletteDropMenu[1]);
brightness = 5;
drawRoulette();
brightness = 15;
while (!isButtonPressed) {
checkJoyStickState();
while (buttonYMoved) {
checkJoyStickState();
lcd.setCursor(1, 0);
lcd.print(rouletteDropMenu[rouletteLine]);
lcd.setCursor(1, 1);
lcd.print(rouletteDropMenu[(rouletteLine + 1) % 3]); // Zeigt das nächste Menüelement an
brightness = 5;
drawRoulette();
// Update des roulette Line und der variablen
if (rouletteLine == 1) {
rouletteLine = 2;
onBlack = true;
brightness = 15;
drawOnBlack();
} else if (rouletteLine == 2) {
rouletteLine = 3;
onRed = true;
brightness = 15;
drawOnRed();
} else if (rouletteLine == 3){
rouletteLine = 0;
onGreen = true;
brightness = 15;
drawOnGreen();
}
else { // rouletteLine == 0
rouletteLine = 1;
onNummber = true;
brightness = 15;
drawRoulette();
}
// Rücksetzen der anderen Variablen
onNummber = (gameLevel == 1);
onBlack = (gameLevel == 2);
onRed = (gameLevel == 3);
onGreen = (gameLevel == 0);
while (buttonYMoved) {
checkJoyStickState();
}
}
}
}
void gameMenu() {
gameLevel = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-");
lcd.setCursor(1, 0);
lcd.print(gameLevelMenu[0]);
lcd.setCursor(1, 1);
lcd.print(gameLevelMenu[1]);
checkJoyStickState();
while (!isButtonPressed) {
checkJoyStickState();
while (buttonYMoved) {
checkJoyStickState();
lcd.setCursor(1, 0);
lcd.print(gameLevelMenu[gameLevel]);
lcd.setCursor(1, 1);
lcd.print(gameLevelMenu[(gameLevel + 1) % 3]); // Zeigt das nächste Menüelement an
// Update des gameLevel und der Statusvariablen
if (gameLevel == 1) {
gameLevel = 2;
threeInARow = true;
} else if (gameLevel == 2) {
gameLevel = 0;
crossUp = true;
} else { // gameLevel == 0
gameLevel = 1;
roulette = true;
}
// Rücksetzen der anderen Variablen
roulette = (gameLevel == 1);
threeInARow = (gameLevel == 2);
crossUp = (gameLevel == 0);
while (buttonYMoved) {
checkJoyStickState();
}
}
}
}
void taskIntro() {
lcd.clear();
while (!isButtonPressed) {
checkJoyStickState();
showTaskField();
delay(50);
showEmptyField();
delay(50);
}
updateText();
resetDisplayAdd();
displayAdd[1] = true;
space = 0;
displayText();
while(isButtonPressed) {checkJoyStickState();}
waitForRightButton();
lcd.setCursor(0, 0);
lcd.print(tasksWords[0]);
lcd.setCursor(0, 1);
lcd.print(tasksWords[1]);
waitForRightButton();
menu();
while (!(menuLine == 2)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("not unlocked now");
lcd.setCursor(0, 1);
lcd.print("You return in 2 ");
delay(1000);
lcd.setCursor(14, 1);
lcd.print("1");
delay(1000);
menu();
}
}
void menu() {
waitForRightButton();
menuLine = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-");
lcd.print(menuWords[0]);
lcd.setCursor(1, 1);
lcd.print(menuWords[1]);
checkJoyStickState();
while (!isButtonPressed) {
checkJoyStickState();
while (buttonYMoved) {
checkJoyStickState();
lcd.setCursor(1, 0);
lcd.print(menuWords[menuLine]);
lcd.setCursor(1, 1);
lcd.print(menuWords[(menuLine + 1) % 4]); // Zeige das nächste Menüelement an
// Aktualisiere den Menüstatus
game = (menuLine == 0);
highscore = (menuLine == 1);
leave = (menuLine == 2);
task = (menuLine == 3);
// Update der menuLine
menuLine = (menuLine + 1) % 4; // Zirkulieren zwischen 0 und 3
while (buttonYMoved) {
checkJoyStickState();
}
}
}
// Setze den Status entsprechend der finalen menuLine
game = (menuLine == 0);
highscore = (menuLine == 1);
leave = (menuLine == 2);
task = (menuLine == 3);
}
void nameChosing() {
updateText();
space = johnPorkSpace;
displayAdd[0] = true;
displayAdd[1] = true;
int nameLine = 1;
lcd.clear();
showJohnPork();
delay(200);
text1++;
text2++;
lcd.setCursor(3, 0);
lcd.print(introWords[text1]);
delay(500);
showFreakBob();
delay(200);
lcd.setCursor(3, 1);
lcd.print(introWords[text2]);
waitForLeftButton();
displayText();
waitForLeftButton();
updateText();
displayText();
waitForRightButton();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-");
lcd.print(people[0]);
lcd.setCursor(1, 1);
lcd.print(people[1]);
lcd.setCursor(0, 0);
lcd.print("-");
checkJoyStickState();
while (!isButtonPressed) {
checkJoyStickState();
while (buttonYMoved) {
checkJoyStickState();
lcd.setCursor(1, 0);
lcd.print(people[nameLine % 6]); // Modulo für zyklisches Durchlaufen der Namen
lcd.setCursor(1, 1);
lcd.print(people[(nameLine + 1) % 6]); // Nächster Name
nameLine = (nameLine % 6) + 1; // Erhöht nameLine zyklisch zwischen 1 und 6
while (buttonYMoved) {
checkJoyStickState();
}
}
}
// Setze den entsprechenden Namen auf true
character[(nameLine - 1) % 6] = true;
while(isButtonPressed) {
checkJoyStickState();
}
space = 2;
updateText();
displayText();
lcd.setCursor(4,1);
for (int i = 0; i < 6; i++) {
if (character[i]) {
lcd.print(people[i]);
break; // Schleife verlassen, sobald der Name gefunden ist
}
}
waitForRightButton();
resetDisplayAdd();
displayAdd[0] = true;
updateText();
space = johnPorkSpace;
displayText();
delay(1250);
}
void johnPorkIntro() {
updateText();
displayText();
playLetsGoGambling();
waitForRightButton();
updateText();
displayText();
delay(500);
displayText();
waitForRightButton();
}
void freakBobIntro() {
space = 0;
resetDisplayAdd();
displayAdd[1] = true;
updateText();
displayText();
delay(1000);
displayText();
delay(1000);
displayText();
delay(500);
displayText();
waitForMenuButton();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-");
lcd.print(menuWords[0]);
lcd.setCursor(1, 1);
lcd.print(menuWords[1]);
delay(1250);
lcd.setCursor(14, 0);
lcd.write(6);
lcd.setCursor(15, 0);
lcd.write(7);
delay(250);
updateText();
displayText();
delay(1000);
displayText();
delay(1000);
displayText();
while(isButtonPressed){checkJoyStickState();}
waitForButton();
}
void playLetsGoGambling() {
for (int i = 0; i < sizeof(goGamblingTone) / sizeof(goGamblingTone[0]); i++) {
int duration = 1000 / goGamblingDuration[i];
tone(melodyPin, goGamblingTone[i], duration);
delay(duration * 1.4); // Pause zwischen den Noten
noTone(melodyPin);
}
}
void playMelody() {
for (int i = 0; i < sizeof(ringTone) / sizeof(int); i++) {
int duration = 1000 / ringToneDuration[i];
tone(melodyPin, ringTone[i], duration);
delay(duration * 1.4); // Pause zwischen den Noten
noTone(melodyPin);
}
}
void showJohnPork() {
lcd.createChar(0, JohnPorkUL);
lcd.createChar(1, JohnPorkUR);
lcd.createChar(2, JohnPorkLL);
lcd.setCursor(0, 0);
lcd.write(0);
lcd.write(1);
lcd.setCursor(0, 1);
lcd.write(2);
lcd.write(3);
}
void showFreakBob() {
lcd.setCursor(14, 0);
lcd.write(4);
lcd.write(5);
lcd.setCursor(14, 1);
lcd.write(6);
lcd.write(7);
}
void showTaskField() {
lcd.createChar(0, taskFieldLow);
lcd.createChar(1, taskFieldUp);
lcd.setCursor(15, 0);
lcd.write(1);
lcd.setCursor(15, 1);
lcd.write(0);
}
void showEmptyField() {
lcd.createChar(2, emptyField);
lcd.setCursor(15, 0);
lcd.write(2);
lcd.setCursor(15, 1);
lcd.write(2);
}
void waitForButton() {
while (!buttonYMoved && !isButtonPressed) {
checkJoyStickState();
}
while (buttonYMoved || isButtonPressed) {
checkJoyStickState();
}
}
void waitForLeftButton() {
while (!buttonYMoved) {
checkJoyStickState();
}
while (buttonYMoved) {
checkJoyStickState();
}
}
void waitForMenuButton() {
while (!isButtonPressed || !buttonYMoved) {
checkJoyStickState();
}
while (buttonYMoved && isButtonPressed) {
checkJoyStickState();
}
}
void waitForRightButton() {
while (!isButtonPressed) {
checkJoyStickState();
}
while (isButtonPressed) {
checkJoyStickState();
}
}
void checkJoyStickState() {
int buttonValueX = analogRead(X_pin);
int buttonValueY = analogRead(Y_pin);
isButtonPressed = !digitalRead(SW_pin);
Serial.println(isButtonPressed);
if (buttonValueX > 450 && buttonValueX < 550) {
buttonXMoved = false;
}
else {
buttonXMoved = true;
}
if (buttonValueY > 450 && buttonValueY < 550) {
buttonYMoved = false;
}
else {
buttonYMoved = true;
}
}
void drawRoulette() {
int centerX = 4; // Mittelpunkt der Matrix
int centerY = 4; // Mittelpunkt der Matrix
int radius = 3; // Radius des Kreises
// Setze die Helligkeit für beide Zeichnungen auf maximal (15)
mx.control(MD_MAX72XX::INTENSITY, brightness);
// Zeichne den Kreis
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
// Berechne den Abstand von der Mitte
int dx = x - centerX;
int dy = y - centerY;
// Wenn der Abstand weniger als der Radius ist, setze die LED
if (dx * dx + dy * dy <= radius * radius) {
mx.setPoint(x, y, 1); // LED im starken Licht einschalten
}
}
}
// Zeichne den 2x2 Block in der Mitte
int startX = 3; // Startposition für den 2x2 Block
int startY = 3; // Startposition für den 2x2 Block
for (int y = startY; y < startY + 2; y++) {
for (int x = startX; x < startX + 2; x++) {
mx.setPoint(x, y, 1); // LED im starken Licht einschalten
}
}
mx.update(); // Aktualisiere die Anzeige der Matrix
}
void drawOnGreen() {
int startX = 3; // Startposition für den 2x2 Block
int startY = 3; // Startposition für den 2x2 Block
// Setze den 2x2 Block in der Mitte auf volle Helligkeit
for (int y = startY; y < startY + 2; y++) {
for (int x = startX; x < startX + 2; x++) {
mx.setPoint(x, y, 1); // LED im starken Licht einschalten
}
}
mx.control(MD_MAX72XX::INTENSITY, brightness);
mx.update(); // Aktualisiere die Anzeige der Matrix
}
void drawOnRed() {
int centerX = 4; // Mittelpunkt der Matrix
int centerY = 4; // Mittelpunkt der Matrix
int radius = 3; // Radius des Kreises
// Setze die Helligkeit für den Kreis auf maximal (15)
mx.control(MD_MAX72XX::INTENSITY, brightness);
// Zeichne den hohlen Kreis
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
// Berechne den Abstand von der Mitte
int dx = x - centerX;
int dy = y - centerY;
// Überprüfe, ob die LED sich am Rand des Kreises befindet
if (dx * dx + dy * dy >= (radius - 1) * (radius - 1) && dx * dx + dy * dy <= radius * radius) {
// Jedes 2. Licht an oder aus
if ((dx + dy) % 2 == 0) { // Muster für jedes zweite Licht
mx.setPoint(x, y, 1); // LED im starken Licht einschalten
} else {
mx.setPoint(x, y, 0); // LED im schwachen Licht ausschalten
}
}
}
}
mx.update(); // Aktualisiere die Anzeige der Matrix
}
void drawOnBlack() {
int centerX = 4; // Mittelpunkt der Matrix
int centerY = 4; // Mittelpunkt der Matrix
int radius = 3; // Radius des Kreises
// Setze die Helligkeit für den Kreis auf maximal (15)
mx.control(MD_MAX72XX::INTENSITY, brightness);
// Zeichne den hohlen Kreis
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
// Berechne den Abstand von der Mitte
int dx = x - centerX;
int dy = y - centerY;
// Überprüfe, ob die LED sich am Rand des Kreises befindet
if (dx * dx + dy * dy >= (radius - 1) * (radius - 1) && dx * dx + dy * dy <= radius * radius) {
// Jedes 2. Licht an oder aus
if ((dx + dy) % 2 == 0) { // Muster für jedes zweite Licht
mx.setPoint(x, y, 0); // LED im schwachen Licht ausschalten
} else {
mx.setPoint(x, y, 1); // LED im starken Licht einschalten
}
} else {
// LED, die nicht im Kreis ist, wird ausgeschaltet
mx.setPoint(x, y, 0); // LED im schwachen Licht ausschalten
}
}
}
mx.update(); // Aktualisiere die Anzeige der Matrix
}