#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const char* VERSION = "1.0";
// Erstellen Sie ein Objekt für das LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Setzen Sie die LCD-Adresse auf 0x27 für ein 16-Zeichen-2-Zeilen-Display
uint8_t diceImages[8][7]=
{
{0,0,0,0,0,0,0}, //0 = alle LED's aus
{0,0,0,0,0,0,1}, //1
{0,1,0,0,1,0,0}, //2
{1,0,0,0,0,1,1}, //3
{1,0,1,1,0,1,0}, //4
{1,0,1,1,0,1,1}, //5
{1,1,1,1,1,1,0}, //6
{1,1,1,1,1,1,1}}; //7 = alle LED's an
const uint8_t START_VIEW = 1;
const uint8_t PLAYER_CHOICE = 2;
const uint8_t GAME_VIEW = 3;
const uint8_t ENEMY_CHOICE = 4;
const uint8_t ENEMY_INIT_CHOICE = 5;
const uint8_t PLAYER_INIT_CHOICE = 7;
const uint8_t RUNNING_FIGHT = 8;
const uint8_t ADD_ENEMY = 9;
const uint8_t ALERT_VIEW = 10;
const uint8_t MENU = 15;
const uint8_t GREEN = 9;
const uint8_t RED = 10;
const uint8_t YELLOW = 11;
const int LONG_PRESS_TIME = 1000;
uint8_t state = START_VIEW;
uint8_t lastState = START_VIEW; // For menu
uint8_t savedState = START_VIEW; // For alert if used
uint8_t playerCount = 1;
bool startDmDices = false;
// MENU
char* menuItems[] = {"Add Enemy", "Exit menu"}; // Fügen Sie weitere Menüpunkte hinzu, falls gewünscht
char currentItem = menuItems[0];
uint8_t MENU_LENGTH = sizeof(menuItems) / sizeof(menuItems[0]);
uint8_t currentMenuItem = 0; // aktueller Menüpunkt
uint8_t topDisplayedItem = 0; // oberster angezeigter Menüpunkt auf dem LCD
// MENU
// FIGHT
struct Initiative {
String name;
uint8_t value;
};
// Globales Array, das die sortierten Initiativen speichert
Initiative initiatives[27]; // Max size
bool fightRunning = false;
uint8_t addMoreEnemies = 0;
uint8_t currentRound = 1;
uint8_t currentInitIndex = 0;
uint8_t enemyCount = 0;
uint8_t enemyInitiative[20] = {0}; // {20,10,15}; // max 20 enemies
uint8_t playerInitiative[7] = {0}; // {18,17,9,8};
bool enemyInitEdited[20] = {false};
bool playerInitEdited[7] = {false};
// E1, P1, P2, E3, E2, P3, P4 -> Order to test
// -> PLAYER_CHOICE
uint8_t currentPlayerInitIndex = 0;
uint8_t lastHandledPlayerIndex = -1;
// -> ENEMY_CHOICE
uint8_t currentEnemyInitIndex = 0;
uint8_t lastHandledEnemyIndex = -1;
// FIGHT
// ALERT
enum AlertResult {
YES,
NO
};
bool alertWasOpen = false;
String alertText = "Override? ";
AlertResult alertResult = YES;
// ALERT
enum ButtonPressType {
NONE,
SHORT_PRESS,
LONG_PRESS
};
struct ButtonState {
long pressStartTime = 0; // Zeitpunkt, zu dem der Button gedrückt wurde
bool wasPressed = false; // Zustand des Buttons im letzten Durchlauf
bool longPressDetected = false; // LONG_PRESS wurde erkannt
};
ButtonState buttonStates[3]; // Zustände für jeden Button
void setup() {
Serial.begin(115200);
// put your setup code here, to run once:
lcd.init(); // Initialisieren Sie das LCD
lcd.backlight(); // Aktivieren Sie die Hintergrundbeleuchtung
lcd.setCursor(0, 0); // Setzen Sie den Cursor in die obere linke Ecke
lcd.print("Welcome v" + String(VERSION)); // Zeigen Sie den Text "Hallo, Welt!" an
lcd.setCursor(2, 1); // Setzen Sie den Cursor in die obere linke Ecke
lcd.print("-= DM PRO =- "); // Zeigen Sie den Text "Hallo, Welt!" an
for (uint8_t i = 2; i <= 2 + 6; ++i) {
pinMode(i,OUTPUT);
}
// DM
pinMode(8, OUTPUT);
// Buttons
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
delay(2000);
// // Funktion aufrufen
// sortInitiatives(playerInitiative, enemyInitiative, 4, 3);
// // Ergebnis ausgeben
// for (int i = 0; i < (3 + 4); ++i) {
// lcd.setCursor(0, 0);
// lcd.print(initiatives[i].name + ": " + String(initiatives[i].value) + " ");
// delay(2000);
// }
// delay(1000);
}
void loop() {
ButtonPressType greenButton = checkButtonPress(GREEN, buttonStates[0]);
ButtonPressType yellowButton = checkButtonPress(YELLOW, buttonStates[1]);
ButtonPressType redButton = checkButtonPress(RED, buttonStates[2]);
//dMDices();
if (yellowButton == LONG_PRESS && state != MENU && state == RUNNING_FIGHT) {
lastState = state;
state = MENU;
}
switch (state) {
case MENU:
if (yellowButton == SHORT_PRESS) {
currentMenuItem++;
if (currentMenuItem >= MENU_LENGTH) {
currentMenuItem = 0;
topDisplayedItem = 0;
} else if (currentMenuItem - topDisplayedItem > 1) {
topDisplayedItem++;
}
}
if (greenButton == SHORT_PRESS) {
String selectedMenuItem = String(menuItems[currentMenuItem]);
selectedMenuItem.toLowerCase();
if (selectedMenuItem == "exit menu") {
state = lastState;
} else if (selectedMenuItem == "add enemy") {
addMoreEnemies = 1;
state = ADD_ENEMY;
}
}
displayMenu();
break;
case START_VIEW:
displayWelcomeMessage();
if (greenButton == SHORT_PRESS) {
state = PLAYER_CHOICE;
}
break;
case ADD_ENEMY:
displayAddNewEnemyView();
if (yellowButton == SHORT_PRESS) {
if (enemyCount + addMoreEnemies + 1 <= 20) { // max 20
addMoreEnemies ++;
}
} else if (redButton == SHORT_PRESS) {
if (addMoreEnemies > 1) { // min 1
addMoreEnemies --;
}
} else if (redButton == LONG_PRESS) {
addMoreEnemies = 0;
state = lastState;
} else if (greenButton == LONG_PRESS) {
currentEnemyInitIndex = enemyCount;
state = ENEMY_INIT_CHOICE;
}
break;
case PLAYER_CHOICE:
displayPlayerChoice(playerCount);
if (redButton == LONG_PRESS) {
state = START_VIEW;
} else if (yellowButton == SHORT_PRESS) {
playerCount++;
if (playerCount > 7) {
playerCount = 1;
}
} else if (greenButton == SHORT_PRESS) {
state = GAME_VIEW;
}
break;
case GAME_VIEW:
displayGameView();
if (greenButton == SHORT_PRESS) {
state = ENEMY_CHOICE;
} else if (redButton == LONG_PRESS) {
state = PLAYER_CHOICE;
}
break;
case ENEMY_CHOICE:
displayEnemyChoice(enemyCount);
if (yellowButton == SHORT_PRESS) {
enemyCount ++;
} else if (greenButton == SHORT_PRESS) {
if (enemyCount > 0) {
state = ENEMY_INIT_CHOICE;
}
} else if (redButton == LONG_PRESS) {
state = GAME_VIEW;
}
break;
case ENEMY_INIT_CHOICE:
displayEnemyInitiativeChoice(currentEnemyInitIndex);
if (greenButton == SHORT_PRESS) {
alertWasOpen = false;
lastHandledEnemyIndex = -1;
currentEnemyInitIndex ++;
if (currentEnemyInitIndex + 1 > enemyCount + addMoreEnemies) {
if (addMoreEnemies > 0) {
currentEnemyInitIndex = enemyCount;
} else {
currentEnemyInitIndex = 0;
}
}
break;
} else if (redButton == LONG_PRESS) {
alertWasOpen = false;
state = ENEMY_CHOICE;
} else if (yellowButton == SHORT_PRESS || redButton == SHORT_PRESS) {
bool addIt = yellowButton == SHORT_PRESS;
if (lastHandledEnemyIndex != currentEnemyInitIndex && enemyInitEdited[currentEnemyInitIndex]) {
if (alertWasOpen) {
alertWasOpen = false;
if (alertResult == YES) {
lastHandledEnemyIndex = currentEnemyInitIndex;
enemyInitiative[currentEnemyInitIndex] += addIt ? 1 : -1;
if (enemyInitiative[currentEnemyInitIndex] < -5) {
enemyInitiative[currentEnemyInitIndex] = 40;
} else if (enemyInitiative[currentEnemyInitIndex] > 40) {
enemyInitiative[currentEnemyInitIndex] = -5;
}
break;
}
alertResult = YES; // Set back to default;
}
alertText = fillString("Override?");
savedState = ENEMY_INIT_CHOICE;
state = ALERT_VIEW;
break;
} else {
lastHandledEnemyIndex = currentEnemyInitIndex;
enemyInitEdited[currentEnemyInitIndex] = true;
enemyInitiative[currentEnemyInitIndex] += addIt ? 1 : -1;
if (enemyInitiative[currentEnemyInitIndex] < -5) {
enemyInitiative[currentEnemyInitIndex] = 40;
} else if (enemyInitiative[currentEnemyInitIndex] > 40) {
enemyInitiative[currentEnemyInitIndex] = -5;
}
break;
}
} else if (yellowButton == LONG_PRESS) {
if (lastHandledEnemyIndex != currentEnemyInitIndex && enemyInitEdited[currentEnemyInitIndex]) {
if (alertWasOpen) {
alertWasOpen = false;
if (alertResult == YES) {
lastHandledEnemyIndex = currentEnemyInitIndex;
enemyInitiative[currentEnemyInitIndex] += 5;
if (enemyInitiative[currentEnemyInitIndex] > 40) {
enemyInitiative[currentEnemyInitIndex] = 40;
}
break;
}
alertResult = YES; // Set back to default;
}
alertText = fillString("Override?");
savedState = ENEMY_INIT_CHOICE;
state = ALERT_VIEW;
break;
} else {
lastHandledEnemyIndex = currentEnemyInitIndex;
enemyInitEdited[currentEnemyInitIndex] = true;
enemyInitiative[currentEnemyInitIndex] += 5;
if (enemyInitiative[currentEnemyInitIndex] > 40) {
enemyInitiative[currentEnemyInitIndex] = 40;
}
break;
}
} else if (greenButton == LONG_PRESS) {
alertWasOpen = false;
if (addMoreEnemies == 0) {
state = PLAYER_INIT_CHOICE;
break;
} else {
String currentPlayerOrEnemy = initiatives[currentInitIndex].name;
addAdditionalEnemies(addMoreEnemies);
enemyCount += addMoreEnemies;
sortInitiativesArray(); // Sort again: New enemies are available
uint8_t newIndex = findIndexByName(currentPlayerOrEnemy);
currentInitIndex += newIndex - currentInitIndex;
addMoreEnemies = 0;
state = RUNNING_FIGHT;
break;
}
}
break;
case PLAYER_INIT_CHOICE:
displayPlayersInitiativeChoice(currentPlayerInitIndex);
if (greenButton == SHORT_PRESS) {
lastHandledPlayerIndex = -1;
alertWasOpen = false;
currentPlayerInitIndex ++;
if (currentPlayerInitIndex + 1 > playerCount) {
currentPlayerInitIndex = 0;
}
break;
} else if (redButton == LONG_PRESS) {
alertWasOpen = false;
state = ENEMY_INIT_CHOICE;
} else if (yellowButton == SHORT_PRESS || redButton == SHORT_PRESS) {
bool addIt = yellowButton == SHORT_PRESS;
if (lastHandledPlayerIndex != currentPlayerInitIndex && playerInitEdited[currentPlayerInitIndex]) {
if (alertWasOpen) {
alertWasOpen = false;
if (alertResult == YES) {
lastHandledPlayerIndex = currentPlayerInitIndex;
playerInitiative[currentPlayerInitIndex] += addIt ? 1 : -1;
if (playerInitiative[currentPlayerInitIndex] < -5) {
playerInitiative[currentPlayerInitIndex] = 40;
} else if (playerInitiative[currentPlayerInitIndex] > 40) {
playerInitiative[currentPlayerInitIndex] = -5;
}
break;
}
alertResult = YES; // Set back to default;
}
alertText = fillString("Override?");
savedState = PLAYER_INIT_CHOICE;
state = ALERT_VIEW;
break;
} else {
lastHandledPlayerIndex = currentPlayerInitIndex;
playerInitEdited[currentPlayerInitIndex] = true;
playerInitiative[currentPlayerInitIndex] += addIt ? 1 : -1;
if (playerInitiative[currentPlayerInitIndex] < -5) {
playerInitiative[currentPlayerInitIndex] = 40;
} else if (playerInitiative[currentPlayerInitIndex] > 40) {
playerInitiative[currentPlayerInitIndex] = -5;
}
break;
}
} else if (yellowButton == LONG_PRESS) {
if (lastHandledPlayerIndex != currentPlayerInitIndex && playerInitEdited[currentPlayerInitIndex]) {
if (alertWasOpen) {
alertWasOpen = false;
if (alertResult == YES) {
lastHandledPlayerIndex = currentPlayerInitIndex;
//playerInitiative[currentPlayerInitIndex] += 5;
if (playerInitiative[currentPlayerInitIndex] > 40) {
playerInitiative[currentPlayerInitIndex] = 40;
}
break;
}
alertResult = YES; // Set back to default;
}
alertText = fillString("Override?");
savedState = PLAYER_INIT_CHOICE;
state = ALERT_VIEW;
break;
} else {
lastHandledPlayerIndex = currentPlayerInitIndex;
playerInitEdited[currentPlayerInitIndex] = true;
playerInitiative[currentPlayerInitIndex] += 5;
if (playerInitiative[currentPlayerInitIndex] > 40) {
playerInitiative[currentPlayerInitIndex] = 40;
}
break;
}
} else if (greenButton == LONG_PRESS) {
alertWasOpen = false;
state = RUNNING_FIGHT;
break;
}
break;
case RUNNING_FIGHT:
displayRunningFightView();
// if (fightRunning) {
// uint8_t playerNumber;
// if (isPlayerString(initiatives[currentInitIndex].name, playerNumber)) {
// showNumber(playerNumber);
// } else {
// //showNumber(0);
// dMDices();
// }
// } else {
// showNumber(0);
// }
// Go crazy :-)
if (greenButton == SHORT_PRESS) {
if (!fightRunning) {
fightRunning = true; // Start game
sortInitiatives(playerInitiative, enemyInitiative, playerCount, enemyCount);
break;
}
} else if (yellowButton == SHORT_PRESS) {
currentInitIndex ++;
if (currentInitIndex + 1 > playerCount + enemyCount) {
// Start next round
currentRound ++;
currentInitIndex = 0;
}
} else if (redButton == LONG_PRESS) {
if (fightRunning) {
// if (alertWasOpen) {
// alertWasOpen = false;
// if (alertResult == YES) {
// resetAllSettings();
// state = GAME_VIEW;
// break;
// }
// alertResult = YES; // Set back to default;
// }
alertResult = NO; // Standard for game
alertText = fillString("Cancel game?");
savedState = RUNNING_FIGHT;
state = ALERT_VIEW;
break;
} else {
resetAllSettings();
state = GAME_VIEW;
break;
}
}
if (alertWasOpen) {
alertWasOpen = false;
if (alertResult == YES) {
Serial.println("RESET HERE");
resetAllSettings();
state = GAME_VIEW;
break;
}
alertResult = YES; // Set back to default;
}
break;
case ALERT_VIEW:
displayAlert();
if (greenButton == SHORT_PRESS) {
alertWasOpen = true;
alertText = fillString("Override?");
state = savedState;
} else if (yellowButton == SHORT_PRESS) {
if (alertResult == YES) {
alertResult = NO;
} else {
alertResult = YES;
}
}
break;
}
if (fightRunning) {
uint8_t playerNumber;
if (isPlayerString(initiatives[currentInitIndex].name, playerNumber)) {
showNumber(playerNumber);
} else {
//showNumber(0);
dMDices();
}
} else {
showNumber(0);
}
// put your main code here, to run repeatedly:
// showNumber(1);
// delay(1000);
// showNumber(2);
// delay(1000);
// showNumber(3);
// delay(1000);
// showNumber(4);
// delay(1000);
// showNumber(5);
// delay(1000);
// showNumber(6);
// delay(1000);
// showNumber(7);
// delay(1000);
}
// HELPER
// Schreibt eine leere Zeile
void writeEmptyLine(uint8_t lineNumber) {
lcd.setCursor(0, lineNumber);
lcd.print(fillString(""));
}
// Füllt einen Text mit Leerzeichen auf für das Display mit 16 Zeichen
String fillString(String input) {
return fillString(input, 16); // Ruft die zweite Funktion mit dem Standardwert auf
}
// Funktionsdefinition mit dem zusätzlichen Parameter
String fillString(String input, uint8_t targetLength) {
uint8_t length = input.length();
if (length >= targetLength) {
return input;
}
for (uint8_t i = length; i < targetLength; i++) {
input += " ";
}
return input;
}
// Format numbers to a string with 2 places "00"
String formatTwoDigits(uint8_t number) {
if (number > 99) {
return "00"; // oder eine Fehlermeldung zurückgeben
}
if (number < 0 && number > -10) {
return "-0" + String(number * -1);
} else if (number <= -10) {
return "-" + String(number * -1);
}
if (number < 10) {
return "0" + String(number);
}
return String(number);
}
// Funktion, die zwei Arrays nimmt, ein Initiative-Array erstellt und dieses sortiert
void sortInitiatives(const uint8_t playerInitiatives[], const uint8_t enemyInitiatives[], uint8_t playerSize, uint8_t enemySize) {
// Spieler-Initiativen hinzufügen
for (uint8_t i = 0; i < playerSize; ++i) {
initiatives[i].name = "Player " + String(i + 1);
initiatives[i].value = playerInitiatives[i];
}
// Feind-Initiativen hinzufügen
for (uint8_t i = 0; i < enemySize; ++i) {
initiatives[i + playerSize].name = "Enemy " + String(i + 1);
initiatives[i + playerSize].value = enemyInitiatives[i];
}
sortInitiativesArray();
}
// Helper for multiple use
void sortInitiativesArray() {
// Liste nach value und dann nach name sortieren
for (uint8_t i = 0; i < playerCount + enemyCount - 1; ++i) {
for (uint8_t j = i + 1; j < playerCount + enemyCount; ++j) {
if (initiatives[i].value < initiatives[j].value ||
(initiatives[i].value == initiatives[j].value && initiatives[i].name > initiatives[j].name)) {
Initiative temp = initiatives[i];
initiatives[i] = initiatives[j];
initiatives[j] = temp;
}
}
}
}
// Add more enemies while fight is running
void addAdditionalEnemies(uint8_t count) {
uint8_t currentCount = playerCount + enemyCount;
for (uint8_t i = 0; i < count; ++i) {
initiatives[i + currentCount].name = "Enemy " + String(i + enemyCount + 1);
initiatives[i + currentCount].value = enemyInitiative[i + enemyCount];
}
}
// Check if current initiative index is a player or an enemy
bool isPlayerString(const String& input, uint8_t& playerNumber) {
// Überprüfen, ob der String mit "Player " beginnt
if (input.startsWith("Player ")) {
// Extrahieren des letzten Zeichens des Strings
char lastChar = input.charAt(input.length() - 1);
// Überprüfen, ob das letzte Zeichen eine Ziffer zwischen 0 und 9 ist
if (lastChar >= '0' && lastChar <= '9') {
// Konvertieren des letzten Zeichens in eine Zahl
playerNumber = lastChar - '0';
return true;
}
}
// Wenn die Bedingungen nicht erfüllt sind, return false
return false;
}
// After fight reset all settings
void resetAllSettings() {
// Reset all arrays
for (int i = 0; i < 20; i++) {
enemyInitiative[i] = 0;
enemyInitEdited[i] = false;
if (i < 7) {
playerInitiative[i] = 0;
playerInitEdited[i] = false;
}
}
for (int i = 0; i < 27; i++) {
initiatives[i].name = "";
initiatives[i].value = 0;
}
// Player and enemy things
addMoreEnemies = 0;
currentEnemyInitIndex = 0;
lastHandledEnemyIndex = -1;
currentPlayerInitIndex = 0;
lastHandledPlayerIndex = -1;
// Reset fight
fightRunning = false;
currentRound = 1;
currentInitIndex = 0;
enemyCount = 0;
// disable dice lights
showNumber(0);
}
// Find index of enemy or player in
int findIndexByName(const String& nameToFind) {
for (int i = 0; i < enemyCount + playerCount; i++) {
if (initiatives[i].name == nameToFind) {
return i; // Index des gefundenen Elements
}
}
return -1; // Name wurde nicht gefunden
}
// HELPER
void showNumber(uint8_t zahl) {
// Für die vom Zufallsgenerator übergebene Nummer wird das passende Bild
// ausgelesen und die passenden LEDs eingeschaltet
for (uint8_t i = 0; i <= 6; ++i) {
digitalWrite(i + 2, diceImages[zahl][i] ? HIGH : LOW);
}
}
void dMDices() {
uint8_t arrLength = 12;
uint8_t values[arrLength] = {2, 1, 0, 6, 2, 2, 1, 0, 6, 3, 4, 5};
int waiting[arrLength] = {800, 80, 80, 80, 80, 800, 80, 80, 80, 80, 80, 80};
static unsigned long previousMillis = 0; // Statische Variable behält ihren Wert zwischen Funktionsaufrufen bei
static uint8_t currentIndex = 0; // Statische Variable behält ihren Wert zwischen Funktionsaufrufen bei
unsigned long currentMillis = millis(); // Die aktuelle Zeit
if (waiting[currentIndex] > 700) {
showNumber(0);
}
// Überprüfen, ob die erforderliche Zeit seit der letzten Aktualisierung vergangen ist
if (currentMillis - previousMillis >= waiting[currentIndex]) {
// Die letzte Aktualisierungszeit auf die aktuelle Zeit setzen
previousMillis = currentMillis;
// Den Wert aus dem Array ausgeben
digitalWrite(values[currentIndex] + 2, HIGH);
int disableLight = currentIndex - 2;
// if (disableLight < -1) {
// // Can only be -2
// disableLight = arrLength - 2;
// } else if (disableLight < 0) {
// disableLight = arrLength - 1;
// }
if (disableLight < 0) {
disableLight = arrLength + disableLight;
}
digitalWrite(values[disableLight] + 2, LOW);
// Zum nächsten Index im Array wechseln
currentIndex++;
// Wenn das Ende des Arrays erreicht ist, von vorne beginnen
if (currentIndex == arrLength) {
currentIndex = 0;
}
}
}
// All about menu
void displayWelcomeMessage() {
lcd.setCursor(0, 0);
lcd.print(" Loaded & ready ");
writeEmptyLine(1);
}
void displayPlayerChoice(uint8_t count) {
lcd.setCursor(0, 0);
lcd.print("Players: " + String(count) + " ");
writeEmptyLine(1);
}
void displayEnemyChoice(uint8_t count) {
lcd.setCursor(0, 0);
lcd.print("Enemies: " + String(count) + " ");
writeEmptyLine(1);
}
void displayEnemyInitiativeChoice(uint8_t index) {
lcd.setCursor(0, 0);
lcd.print(fillString("Enemy: " + String(index + 1)));
lcd.setCursor(0, 1);
lcd.print("Initiative: " + String(formatTwoDigits(enemyInitiative[index])) + " ");
}
void displayPlayersInitiativeChoice(uint8_t index) {
lcd.setCursor(0, 0);
lcd.print("Player: " + String(index + 1) + " ");
lcd.setCursor(0, 1);
lcd.print("Initiative: " + String(formatTwoDigits(playerInitiative[index])) + " ");
}
void displayGameView() {
lcd.setCursor(0, 0);
lcd.print(fillString("Press start to"));
lcd.setCursor(0, 1);
lcd.print(fillString("fight |P:" + String(playerCount)));
}
void displayRunningFightView() {
if (!fightRunning) {
lcd.setCursor(0, 0);
lcd.print(fillString("GREEN to start"));
writeEmptyLine(1);
} else {
// Running game
lcd.setCursor(0, 0);
lcd.print(fillString("ROUND " + String(currentRound)));
lcd.setCursor(0, 1);
lcd.print(fillString(initiatives[currentInitIndex].name + ":", 11));
lcd.setCursor(11, 1);
lcd.print(fillString("I: " + formatTwoDigits(initiatives[currentInitIndex].value), 5));
}
}
void displayAddNewEnemyView() {
lcd.setCursor(0, 0);
lcd.print(fillString("Add new enemies"));
lcd.setCursor(0, 1);
lcd.print(fillString("Amount: " + formatTwoDigits(addMoreEnemies)));
}
void displayMenu() {
byte arrowRight[8] = {
B00000,
B01000,
B01100,
B01110,
B01111,
B01110,
B01100,
B01000
};
lcd.createChar(0, arrowRight);
lcd.setCursor(0, 0);
//lcd.write(byte(0)); // Pfeil nach oben
// Zeige den Pfeil in der richtigen Zeile an
if (currentMenuItem - topDisplayedItem == 0) {
lcd.write(byte(0)); // Pfeil nach oben
} else {
lcd.print(" ");
}
lcd.print(fillString(menuItems[topDisplayedItem]));
lcd.setCursor(0, 1);
if (currentMenuItem - topDisplayedItem == 1) {
lcd.write(byte(0)); // Pfeil nach oben
} else {
lcd.print(" ");
}
if (topDisplayedItem + 1 < MENU_LENGTH) {
lcd.print(fillString(menuItems[topDisplayedItem + 1]));
}
}
void displayAlert() {
byte arrowRight[8] = {
B00000,
B01000,
B01100,
B01110,
B01111,
B01110,
B01100,
B01000
};
lcd.createChar(0, arrowRight);
lcd.setCursor(0, 0);
lcd.print(alertText);
if (alertResult == YES) {
lcd.setCursor(0, 1);
lcd.write(byte(0)); // Pfeil nach oben
lcd.setCursor(1, 1);
lcd.print(" YES NO");
} else {
lcd.setCursor(0, 1);
lcd.print(" YES ");
lcd.setCursor(12, 1);
lcd.write(byte(0)); // Pfeil nach oben
lcd.print(" NO");
}
}
ButtonPressType checkButtonPress(uint8_t buttonPin, ButtonState &state) {
ButtonPressType pressType = NONE;
bool buttonIsPressed = digitalRead(buttonPin) == HIGH;
if (buttonIsPressed) {
delay(20); // Entprellen
buttonIsPressed = digitalRead(buttonPin) == HIGH;
}
if (!state.wasPressed && buttonIsPressed) { // Button wurde gerade gedrückt
state.pressStartTime = millis(); // Startzeit speichern
state.longPressDetected = false;
}
if (state.wasPressed && !buttonIsPressed) { // Button wurde gerade losgelassen
if ((millis() - state.pressStartTime) < LONG_PRESS_TIME && !state.longPressDetected) {
pressType = SHORT_PRESS;
}
} else if (state.wasPressed && buttonIsPressed) { // Button wird gedrückt und LONG_PRESS_TIME ist überschritten
if ((millis() - state.pressStartTime) > LONG_PRESS_TIME) {
state.pressStartTime = millis();
state.longPressDetected = true;
pressType = LONG_PRESS;
}
}
state.wasPressed = buttonIsPressed; // Zustand für den nächsten Durchlauf speichern
return pressType;
}
// --------------