#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Premenné pre hru
int coinX, coinY;
int panacikX = 9, panacikY = 1;
int score = 0;
struct Meteor {
int x, y;
bool active;
bool movingRight;
};
Meteor meteors[2]; // Maximum 2 meteority
int meteorCount = 1; // Počet aktívnych meteoritov
unsigned long lastMeteorMove = 0;
unsigned long meteorDelay = 300;
// Vlastné znaky pre LCD
byte panacik[8] = { B00100, B01010, B00100, B01110, B10101, B00100, B01010, B10001 };
byte minca[8] = { B00000, B00000, B01110, B10001, B10001, B01110, B00000, B00000 };
byte animacia[8] = { B00100, B01010, B10101, B01110, B00100, B00100, B01010, B10001 };
byte meteorit[8] = { B00100, B01110, B11111, B11011, B11111, B01110, B00100, B00000 };
byte explosion[8] = { B01010, B10101, B01010, B11111, B01010, B10101, B01010, B00000 };
void setup() {
// Nastavenie vstupov pre tlačidlá
DDRD &= ~((1 << 2) | (1 << 4) | (1 << 7));
PORTD |= (1 << 2) | (1 << 4) | (1 << 7);
DDRB &= ~(1 << 0);
PORTB |= (1 << 0);
// Inicializácia LCD
lcd.init();
lcd.backlight();
// Registrácia vlastných znakov
lcd.createChar(1, panacik);
lcd.createChar(2, minca);
lcd.createChar(3, animacia);
lcd.createChar(4, meteorit);
lcd.createChar(5, explosion);
// Inicializácia meteoritov
for (int i = 0; i < 2; i++) {
meteors[i] = {0, 0, false, false};
}
startCoinGame();
}
void startCoinGame() {
lcd.clear();
score = 0;
panacikX = 9;
panacikY = 1;
lcd.setCursor(0, 0);
lcd.print("Skore: ");
lcd.print(score);
lcd.setCursor(panacikX, panacikY);
lcd.write(byte(1));
generateCoin();
while (true) {
handleInput();
moveMeteors();
manageMeteorCount();
spawnInactiveMeteors();
}
}
void handleInput() {
if (!(PIND & (1 << 2)) && panacikY > 1) movePanacik(0, -1); // Hore
if (!(PIND & (1 << 4)) && panacikY < 3) movePanacik(0, 1); // Dole
if (!(PIND & (1 << 7)) && panacikX > 0) movePanacik(-1, 0); // Doľava
if (!(PINB & (1 << 0)) && panacikX < 19) movePanacik(1, 0); // Doprava
}
void movePanacik(int x, int y) {
lcd.setCursor(panacikX, panacikY);
lcd.print(" ");
panacikX += x;
panacikY += y;
lcd.setCursor(panacikX, panacikY);
lcd.write(byte(1));
checkCollision();
}
void generateCoin() {
bool validPosition = false;
while (!validPosition) {
coinX = random(0, 20);
coinY = random(1, 4);
validPosition = true;
if (coinX == panacikX && coinY == panacikY) validPosition = false;
if (isMeteorPosition(coinX, coinY)) validPosition = false;
}
lcd.setCursor(coinX, coinY);
lcd.write(byte(2));
}
bool isMeteorPosition(int x, int y) {
for (int i = 0; i < meteorCount; i++) {
if (meteors[i].active && meteors[i].x == x && meteors[i].y == y) return true;
}
return false;
}
void checkCollision() {
for (int i = 0; i < meteorCount; i++) {
if (meteors[i].active && meteors[i].x == panacikX && meteors[i].y == panacikY) endGame();
}
if (panacikX == coinX && panacikY == coinY) {
score++;
lcd.setCursor(0, 0);
lcd.print("Skore: ");
lcd.print(score);
lcd.setCursor(panacikX, panacikY);
lcd.write(byte(3));
delay(200);
lcd.setCursor(panacikX, panacikY);
lcd.write(byte(1));
generateCoin();
}
}
void generateMeteor(int index) {
meteors[index].y = random(1, 4);
meteors[index].movingRight = random(0, 2) == 0 ? false : true;
meteors[index].x = meteors[index].movingRight ? 0 : 19;
meteors[index].active = true;
lcd.setCursor(meteors[index].x, meteors[index].y);
lcd.write(byte(4));
}
void moveMeteors() {
if (millis() - lastMeteorMove < meteorDelay) return;
lastMeteorMove = millis();
for (int i = 0; i < meteorCount; i++) {
if (!meteors[i].active) continue;
lcd.setCursor(meteors[i].x, meteors[i].y);
lcd.print(" ");
meteors[i].x += meteors[i].movingRight ? 1 : -1;
if (meteors[i].x < 0 || meteors[i].x > 19) {
meteors[i].active = false;
continue;
}
lcd.setCursor(meteors[i].x, meteors[i].y);
lcd.write(byte(4));
if (meteors[i].x == panacikX && meteors[i].y == panacikY) endGame();
if (meteors[i].x == coinX && meteors[i].y == coinY) generateCoin();
}
}
void manageMeteorCount() {
if (score >= 11) {
meteorCount = 2;
meteorDelay = (score >= 31) ? 200 : 300;
}
}
void spawnInactiveMeteors() {
for (int i = 0; i < meteorCount; i++) {
if (!meteors[i].active) {
delay(500);
generateMeteor(i);
}
}
}
void endGame() {
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Game Over!");
lcd.setCursor(5, 2);
lcd.print("Skore: ");
lcd.print(score);
while (true);
}