#include <Adafruit_ILI9341.h>
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>
// DEBUG AYARLARI - BU KISMI EKLEYİN
#define DEBUG_SERIAL true // Seri monitör debug mesajları
#define DEBUG_BUTTONS true // Buton durumlarını göster
#define DEBUG_GAME_EVENTS true // Oyun olaylarını göster
#define DEBUG_CREDIT true // Kredi değişimlerini göster
#define DEBUG_INTERRUPTS true // Interrupt olaylarını göster
// Pin Tanımlamaları - WOKWI D pinleri (ORIJINAL HALİ)
#define PLAYER1_START_BTN 26
#define PLAYER1_BURN_BTN 12
// LED pinleri iptal edildi
#define PLAYER1_GAME_LED 13
#define PLAYER2_START_BTN 25
#define PLAYER2_BURN_BTN 34
// LED pinleri iptal edildi
#define PLAYER2_GAME_LED 32
#define COIN_SENSOR 17
// TOTAL_GAMES_BTN iptal edildi
#define GAME_STATUS_LED 35 // 1001 LED için yeni pin
// Addressable LED Pinleri - WOKWI D0 ve D1
#define PLAYER1_PIXEL_PIN 27 // D0 = GPIO 26
#define PLAYER2_PIXEL_PIN 33 // D1 = GPIO 25
#define PIXEL_COUNT 8
// TFT Ekran Pinleri
#define TFT1_CS 5
#define TFT1_RST 22
#define TFT1_DC 21
#define TFT1_MOSI 23
#define TFT1_SCK 18
#define TFT2_CS 4
#define TFT2_RST 2
#define TFT2_DC 15
#define TFT2_MOSI 16
#define TFT2_SCK 14
// EEPROM
#define EEPROM_SIZE 128
#define EEPROM_CREDIT_ADDR 0
#define EEPROM_STATS_ADDR 50
#define EEPROM_MAGIC_NUMBER 123
// INTERRUPT için volatile değişkenler
volatile bool coinInserted = false;
volatile unsigned long lastCoinInterruptTime = 0;
SPIClass hspi(HSPI);
SPIClass vspi(VSPI);
Adafruit_ILI9341 tft1(&vspi, TFT1_DC, TFT1_CS, TFT1_RST);
Adafruit_ILI9341 tft2(&hspi, TFT2_DC, TFT2_CS, TFT2_RST);
LiquidCrystal_I2C lcd1(0x27, 16, 2);
// Addressable LED'ler
Adafruit_NeoPixel player1Pixels(PIXEL_COUNT, PLAYER1_PIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel player2Pixels(PIXEL_COUNT, PLAYER2_PIXEL_PIN, NEO_GRB + NEO_KHZ800);
enum PlayerState { PLAYER_MENU, PLAYER_PLAYING, PLAYER_GAME_OVER };
struct GameStatistics {
unsigned long totalGames, todayGames, totalEarnings, lastResetDay, player1Wins, player2Wins;
};
struct CreditSystem {
int totalCredit, creditPerGame = 50, gamesAvailable;
unsigned long lastCoinTime;
bool lastCoinState;
};
struct Player {
PlayerState state = PLAYER_MENU;
int score = 2000;
bool invincible = false, lastStartBtnState = HIGH, lastBurnBtnState = HIGH;
bool blinkState = false, isBurning = false, hasCredit = false;
unsigned long lastUpdateTime = 0, gameStartTime = 0, gameEndTime = 0;
unsigned long lastBlinkTime = 0, burnStartTime = 0;
Adafruit_ILI9341* tft;
Adafruit_NeoPixel* pixels;
int startBtnPin, burnBtnPin, gameLedPin;
};
// Global değişkenler
Player player1, player2;
CreditSystem creditSystem;
GameStatistics gameStats;
bool showingTotalGames = false, menuBlinkState = true;
unsigned long totalGamesDisplayStartTime = 0, menuLastBlink = 0, lastLcdUpdate = 0;
unsigned long lastAnimationUpdate = 0, lastSaveTime = 0, coinMessageTime = 0;
bool showingCoinMessage = false;
uint8_t animationOffset = 0;
// Buton durumları için değişkenler
bool player1StartPressed = false, player1BurnPressed = false;
bool player2StartPressed = false, player2BurnPressed = false;
unsigned long allButtonsPressedTime = 0;
bool allButtonsActive = false;
// 1001 LED kontrol değişkenleri
bool gameStatusLedActive = false;
unsigned long gameStatusLedStartTime = 0;
const unsigned long GAME_STATUS_LED_DURATION = 2000; // 2 saniye
// DEBUG için değişkenler
unsigned long lastDebugPrint = 0;
const unsigned long DEBUG_INTERVAL = 1000; // 1 saniyede bir debug yazdır
// DEBUG fonksiyonları
void debugPrint(const char* message) {
if (DEBUG_SERIAL) {
Serial.println(message);
}
}
void debugPrintf(const char* format, ...) {
if (DEBUG_SERIAL) {
char buffer[256];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
Serial.println(buffer);
}
}
void printButtonStates() {
if (DEBUG_BUTTONS && DEBUG_SERIAL) {
bool p1Start = digitalRead(PLAYER1_START_BTN);
bool p1Burn = digitalRead(PLAYER1_BURN_BTN);
bool p2Start = digitalRead(PLAYER2_START_BTN);
bool p2Burn = digitalRead(PLAYER2_BURN_BTN);
bool coin = digitalRead(COIN_SENSOR);
debugPrintf("BUTONLAR - P1Start:%d P1Burn:%d P2Start:%d P2Burn:%d Coin:%d",
p1Start, p1Burn, p2Start, p2Burn, coin);
}
}
void printPlayerStates() {
if (DEBUG_GAME_EVENTS && DEBUG_SERIAL) {
debugPrintf("OYUNCU DURUMLARI - P1:%d Skor:%d P2:%d Skor:%d",
player1.state, player1.score, player2.state, player2.score);
}
}
void printCreditInfo() {
if (DEBUG_CREDIT && DEBUG_SERIAL) {
debugPrintf("KREDI - Toplam:%dTL OyunHakki:%d",
creditSystem.totalCredit, creditSystem.gamesAvailable);
}
}
// INTERRUPT fonksiyonu
void IRAM_ATTR coinInterrupt() {
unsigned long currentTime = micros();
if (currentTime - lastCoinInterruptTime > 100000) {
coinInserted = true;
lastCoinInterruptTime = currentTime;
if (DEBUG_INTERRUPTS && DEBUG_SERIAL) {
Serial.println("🎯 COIN INTERRUPT TETIKLENDI!");
}
}
}
void initializeAllOutputs() {
const int outputPins[] = {PLAYER1_GAME_LED, PLAYER2_GAME_LED, GAME_STATUS_LED, TFT1_CS, TFT2_CS, TFT1_RST, TFT1_DC, TFT2_RST, TFT2_DC, PLAYER1_PIXEL_PIN, PLAYER2_PIXEL_PIN};
const int initStates[] = {LOW, LOW, LOW, HIGH, HIGH, LOW, LOW, LOW, LOW, LOW, LOW};
for(int i = 0; i < 11; i++) {
digitalWrite(outputPins[i], initStates[i]);
pinMode(outputPins[i], OUTPUT);
}
}
void initializePlayer(Player* player, Adafruit_ILI9341* tft, Adafruit_NeoPixel* pixels, int startBtn, int burnBtn, int gameLedPin) {
player->tft = tft;
player->pixels = pixels;
player->startBtnPin = startBtn;
player->burnBtnPin = burnBtn;
player->gameLedPin = gameLedPin;
}
void setup() {
Serial.begin(115200);
Serial.println("====================================");
Serial.println("🚀 SISTEM BASLATILIYOR...");
Serial.println("====================================");
initializeAllOutputs();
EEPROM.begin(EEPROM_SIZE);
const int inputPins[] = {PLAYER1_START_BTN, PLAYER1_BURN_BTN, PLAYER2_START_BTN, PLAYER2_BURN_BTN, COIN_SENSOR};
for(int i = 0; i < 5; i++) {
pinMode(inputPins[i], INPUT_PULLUP);
debugPrintf("Buton pin %d ayarlandi: INPUT_PULLUP", inputPins[i]);
}
attachInterrupt(digitalPinToInterrupt(COIN_SENSOR), coinInterrupt, FALLING);
debugPrint("✅ Coin interrupt aktif");
player1Pixels.begin(); player1Pixels.show();
player2Pixels.begin(); player2Pixels.show();
debugPrint("✅ Addressable LED'ler baslatildi");
Wire.begin(19, 0);
delay(1000);
lcd1.begin(16, 2); lcd1.backlight(); lcd1.print("SISTEM HAZIR");
creditSystem.lastCoinState = HIGH;
if(!readCreditData()) {
creditSystem.totalCredit = 0;
creditSystem.gamesAvailable = 0;
saveCreditData();
debugPrint("✅ Kredi verileri ilk kez olusturuldu");
}
if(!readGameStatistics()) {
resetGameStats();
debugPrint("✅ Istatistikler ilk kez olusturuldu");
}
vspi.begin(TFT1_SCK, -1, TFT1_MOSI, TFT1_CS);
hspi.begin(TFT2_SCK, -1, TFT2_MOSI, TFT2_CS);
tft1.begin(); tft1.setRotation(1); tft1.fillScreen(ILI9341_BLACK);
tft2.begin(); tft2.setRotation(1); tft2.fillScreen(ILI9341_BLACK);
debugPrint("✅ TFT ekranlar baslatildi");
initializePlayer(&player1, &tft1, &player1Pixels, PLAYER1_START_BTN, PLAYER1_BURN_BTN, PLAYER1_GAME_LED);
initializePlayer(&player2, &tft2, &player2Pixels, PLAYER2_START_BTN, PLAYER2_BURN_BTN, PLAYER2_GAME_LED);
Serial.println("====================================");
Serial.println("✅ TUM SISTEMLER HAZIR!");
Serial.println("====================================");
updateCreditLCD();
showCreditScreen();
}
bool readCreditData() {
if(EEPROM.readInt(EEPROM_CREDIT_ADDR) == EEPROM_MAGIC_NUMBER) {
creditSystem.totalCredit = EEPROM.readInt(EEPROM_CREDIT_ADDR + 4);
creditSystem.gamesAvailable = EEPROM.readInt(EEPROM_CREDIT_ADDR + 8);
debugPrintf("📊 Kredi okundu: %d TL, Oyun: %d", creditSystem.totalCredit, creditSystem.gamesAvailable);
return true;
}
return false;
}
bool readGameStatistics() {
if(EEPROM.readInt(EEPROM_STATS_ADDR) == EEPROM_MAGIC_NUMBER) {
gameStats.totalGames = EEPROM.readULong(EEPROM_STATS_ADDR + 4);
gameStats.todayGames = EEPROM.readULong(EEPROM_STATS_ADDR + 8);
gameStats.totalEarnings = EEPROM.readULong(EEPROM_STATS_ADDR + 12);
gameStats.lastResetDay = EEPROM.readULong(EEPROM_STATS_ADDR + 16);
gameStats.player1Wins = EEPROM.readULong(EEPROM_STATS_ADDR + 20);
gameStats.player2Wins = EEPROM.readULong(EEPROM_STATS_ADDR + 24);
debugPrintf("📈 Istatistikler okundu: Toplam Oyun=%lu", gameStats.totalGames);
return true;
}
return false;
}
void resetGameStats() {
gameStats.totalGames = 0;
gameStats.todayGames = 0;
gameStats.totalEarnings = 0;
gameStats.lastResetDay = millis()/86400000;
gameStats.player1Wins = 0;
gameStats.player2Wins = 0;
saveGameStatistics();
}
void saveCreditData() {
EEPROM.writeInt(EEPROM_CREDIT_ADDR, EEPROM_MAGIC_NUMBER);
EEPROM.writeInt(EEPROM_CREDIT_ADDR + 4, creditSystem.totalCredit);
EEPROM.writeInt(EEPROM_CREDIT_ADDR + 8, creditSystem.gamesAvailable);
EEPROM.commit();
if (DEBUG_CREDIT) {
debugPrintf("💾 Kredi kaydedildi: %d TL, Oyun: %d", creditSystem.totalCredit, creditSystem.gamesAvailable);
}
}
void saveGameStatistics() {
EEPROM.writeInt(EEPROM_STATS_ADDR, EEPROM_MAGIC_NUMBER);
EEPROM.writeULong(EEPROM_STATS_ADDR + 4, gameStats.totalGames);
EEPROM.writeULong(EEPROM_STATS_ADDR + 8, gameStats.todayGames);
EEPROM.writeULong(EEPROM_STATS_ADDR + 12, gameStats.totalEarnings);
EEPROM.writeULong(EEPROM_STATS_ADDR + 16, gameStats.lastResetDay);
EEPROM.writeULong(EEPROM_STATS_ADDR + 20, gameStats.player1Wins);
EEPROM.writeULong(EEPROM_STATS_ADDR + 24, gameStats.player2Wins);
EEPROM.commit();
}
void loop() {
unsigned long currentTime = millis();
if (coinInserted) {
coinInserted = false;
handleCoin(currentTime);
}
if (showingCoinMessage && currentTime - coinMessageTime >= 2000) {
showingCoinMessage = false;
updateCreditLCD();
}
// Debug bilgilerini belirli aralıklarla yazdır
if (DEBUG_SERIAL && currentTime - lastDebugPrint >= DEBUG_INTERVAL) {
lastDebugPrint = currentTime;
printButtonStates();
printPlayerStates();
printCreditInfo();
Serial.println("---");
}
// Tüm butonların durumunu kontrol et
checkAllButtons(currentTime);
if(showingTotalGames) {
if(currentTime - totalGamesDisplayStartTime >= 7000) {
showingTotalGames = false;
updateCreditLCD();
}
} else if(!showingCoinMessage && currentTime - lastLcdUpdate >= 1000) {
lastLcdUpdate = currentTime;
updateCreditLCD();
}
// 1001 LED durumunu güncelle
updateGameStatusLed(currentTime);
updatePixelAnimations(currentTime);
handlePlayer(&player1, currentTime);
handlePlayer(&player2, currentTime);
if(currentTime - menuLastBlink >= 500) {
menuLastBlink = currentTime;
menuBlinkState = !menuBlinkState;
updateCreditDisplay();
}
if(currentTime - lastSaveTime >= 30000) {
saveCreditData();
saveGameStatistics();
lastSaveTime = currentTime;
debugPrint("💾 Otomatik kayit yapildi");
}
}
void updateGameStatusLed(unsigned long currentTime) {
if (gameStatusLedActive) {
if (currentTime - gameStatusLedStartTime >= GAME_STATUS_LED_DURATION) {
// 2 saniye doldu, LED'i kapat
digitalWrite(GAME_STATUS_LED, LOW);
gameStatusLedActive = false;
debugPrint("🔴 1001 LED kapandi");
}
}
}
void activateGameStatusLed(unsigned long currentTime) {
// LED'i yak ve süreyi başlat/güncelle
digitalWrite(GAME_STATUS_LED, HIGH);
gameStatusLedActive = true;
gameStatusLedStartTime = currentTime;
debugPrint("🟢 1001 LED aktif - 2 saniye");
}
void checkAllButtons(unsigned long currentTime) {
// Tüm butonların mevcut durumunu kontrol et
bool p1Start = digitalRead(PLAYER1_START_BTN) == LOW;
bool p1Burn = digitalRead(PLAYER1_BURN_BTN) == LOW;
bool p2Start = digitalRead(PLAYER2_START_BTN) == LOW;
bool p2Burn = digitalRead(PLAYER2_BURN_BTN) == LOW;
// Eğer tüm butonlar basılıysa
if (p1Start && p1Burn && p2Start && p2Burn) {
if (!allButtonsActive) {
// İlk kez tüm butonlar basıldı
allButtonsActive = true;
allButtonsPressedTime = currentTime;
debugPrint("🎮 TUM BUTONLAR BASILDI - 1 saniye bekleniyor...");
} else if (currentTime - allButtonsPressedTime >= 1000) {
// Tüm butonlar 1 saniyedir basılı durumda
if (!showingTotalGames) {
showingTotalGames = true;
totalGamesDisplayStartTime = currentTime;
lcd1.clear();
lcd1.print("TOPLAM OYUN");
lcd1.setCursor(0,1);
lcd1.print("SAYISI:");
lcd1.print(gameStats.totalGames);
debugPrintf("📊 Toplam oyun gosteriliyor: %lu", gameStats.totalGames);
}
}
} else {
allButtonsActive = false;
}
}
void handleCoin(unsigned long currentTime) {
creditSystem.totalCredit += 5;
creditSystem.gamesAvailable = creditSystem.totalCredit / creditSystem.creditPerGame;
debugPrintf("💵 INTERRUPT - Para atildi! Kredi: %d TL, Oyun: %d", creditSystem.totalCredit, creditSystem.gamesAvailable);
saveCreditData();
lcd1.clear();
lcd1.print("PARA ATILDI!");
lcd1.setCursor(0,1);
lcd1.print("+5 TL");
showingCoinMessage = true;
coinMessageTime = currentTime;
updateCreditDisplay();
}
void updatePixelAnimations(unsigned long currentTime) {
if(currentTime - lastAnimationUpdate >= 50) {
lastAnimationUpdate = currentTime;
animationOffset++;
updatePlayerPixels(&player1, animationOffset);
updatePlayerPixels(&player2, animationOffset + 64);
}
}
void updatePlayerPixels(Player* player, uint8_t offset) {
if(player->isBurning) {
setPixelColor(player->pixels, 255, 0, 0);
} else if(player->state == PLAYER_PLAYING) {
setPixelColor(player->pixels, 0, 255, 0);
} else {
rainbowAnimation(player->pixels, offset);
}
}
void setPixelColor(Adafruit_NeoPixel* pixels, uint8_t r, uint8_t g, uint8_t b) {
for(int i=0; i<pixels->numPixels(); i++) {
pixels->setPixelColor(i, pixels->Color(r, g, b));
}
pixels->show();
}
void rainbowAnimation(Adafruit_NeoPixel* pixels, uint8_t offset) {
for(int i=0; i<pixels->numPixels(); i++) {
uint8_t hue = (offset * 2 + i * 32) % 256;
pixels->setPixelColor(i, Wheel(hue));
}
pixels->show();
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) return Adafruit_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
if(WheelPos < 170) {
WheelPos -= 85;
return Adafruit_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return Adafruit_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void updateCreditLCD() {
lcd1.clear();
lcd1.print("KREDI:");
lcd1.print(creditSystem.totalCredit);
lcd1.print("TL");
lcd1.setCursor(0,1);
lcd1.print("OYUN:");
lcd1.print(creditSystem.gamesAvailable);
lcd1.print(creditSystem.gamesAvailable > 0 ? " YUKLU" : " BOS");
}
void updateCreditDisplay() {
updateTFTDisplay(&player1, &tft1);
updateTFTDisplay(&player2, &tft2);
}
void updateTFTDisplay(Player* player, Adafruit_ILI9341* tft) {
if(player->state != PLAYER_MENU) return;
tft->fillScreen(ILI9341_BLACK);
tft->setTextColor(ILI9341_WHITE);
tft->setTextSize(2);
tft->setCursor(20, 50);
tft->printf("KREDI: %d TL", creditSystem.totalCredit);
tft->setCursor(20, 100);
tft->printf("OYUN HAKKI: %d", creditSystem.gamesAvailable);
if(creditSystem.gamesAvailable > 0) {
tft->setTextColor(ILI9341_GREEN);
tft->setCursor(20, 150);
if(menuBlinkState) tft->print("START BUTONUNA BASIN");
} else {
tft->setTextColor(ILI9341_RED);
tft->setCursor(20, 150);
tft->print("KREDI YUKLEYIN");
}
}
void showCreditScreen() {
updateCreditDisplay();
}
void handlePlayer(Player* player, unsigned long currentTime) {
switch(player->state) {
case PLAYER_MENU:
handlePlayerMenu(player, currentTime);
break;
case PLAYER_PLAYING:
handlePlayerPlaying(player, currentTime);
break;
case PLAYER_GAME_OVER:
handlePlayerGameOver(player, currentTime);
break;
}
if(player->isBurning && currentTime - player->burnStartTime >= 2000) {
player->isBurning = false;
}
}
void handlePlayerMenu(Player* player, unsigned long currentTime) {
bool currentStartBtnState = digitalRead(player->startBtnPin);
// Buton basıldığında (HIGH -> LOW geçişi)
if(player->lastStartBtnState && !currentStartBtnState && currentTime - player->gameStartTime > 500) {
if(creditSystem.gamesAvailable > 0) {
creditSystem.gamesAvailable--;
creditSystem.totalCredit = max(0, creditSystem.totalCredit - creditSystem.creditPerGame);
saveCreditData();
startPlayerGame(player);
debugPrintf("🎮 OYUN BASLATILDI - Oyuncu: %s", (player == &player1) ? "1" : "2");
updateCreditLCD();
} else {
player->tft->fillScreen(ILI9341_RED);
player->tft->setTextColor(ILI9341_WHITE);
player->tft->setTextSize(3);
player->tft->setCursor(40, 100);
player->tft->print("KREDI YOK!");
debugPrintf("❌ KREDI YOK - Oyuncu: %s", (player == &player1) ? "1" : "2");
delay(2000);
updateCreditDisplay();
}
}
player->lastStartBtnState = currentStartBtnState;
}
void handlePlayerPlaying(Player* player, unsigned long currentTime) {
if(!player->invincible && currentTime - player->lastUpdateTime >= 80) {
player->lastUpdateTime = currentTime;
if(--player->score <= 0) {
endPlayerGame(player, "GAME OVER");
// Oyuncu yandığında 1001 LED'i aktif et
activateGameStatusLed(currentTime);
debugPrintf("💀 OYUNCU YANDI - Oyuncu: %s", (player == &player1) ? "1" : "2");
}
else drawPlayerScore(player);
}
bool currentStartBtnState = digitalRead(player->startBtnPin);
if(player->lastStartBtnState && !currentStartBtnState && currentTime - player->gameStartTime > 2000) {
endPlayerGame(player, "FINISHED!");
debugPrintf("🏁 OYUN BITIRILDI - Oyuncu: %s Skor: %d", (player == &player1) ? "1" : "2", player->score);
}
player->lastStartBtnState = currentStartBtnState;
bool currentBurnBtnState = digitalRead(player->burnBtnPin);
if(player->lastBurnBtnState && !currentBurnBtnState && !player->invincible) {
burnAction(player, currentTime);
debugPrintf("🔥 BURN BUTONU - Oyuncu: %s", (player == &player1) ? "1" : "2");
}
player->lastBurnBtnState = currentBurnBtnState;
}
void handlePlayerGameOver(Player* player, unsigned long currentTime) {
if(currentTime - player->lastBlinkTime >= 200) {
player->lastBlinkTime = currentTime;
player->blinkState = !player->blinkState;
drawPlayerFinalScore(player);
}
if(currentTime - player->gameEndTime >= 3000) {
resetPlayer(player);
updateCreditDisplay();
updateCreditLCD();
debugPrintf("🔄 OYUNCU SIFIRLANDI - Oyuncu: %s", (player == &player1) ? "1" : "2");
}
}
void startPlayerGame(Player* player) {
player->state = PLAYER_PLAYING;
player->score = 2000;
player->lastUpdateTime = player->gameStartTime = millis();
digitalWrite(player->gameLedPin, HIGH);
player->tft->fillScreen(ILI9341_GREEN);
drawPlayerScore(player);
}
void endPlayerGame(Player* player, const char* message) {
int winner = (player == &player1) ? 1 : 2;
updateGameStatistics(winner);
player->state = PLAYER_GAME_OVER;
player->gameEndTime = millis();
digitalWrite(player->gameLedPin, LOW);
player->tft->fillScreen(ILI9341_BLACK);
player->tft->setTextColor(ILI9341_RED);
player->tft->setTextSize(2);
player->tft->setCursor(40, 100);
player->tft->print(message);
player->tft->setTextSize(3);
player->tft->setCursor(100, 140);
player->tft->print(player->score);
}
void updateGameStatistics(int winner) {
unsigned long currentDay = millis() / 86400000;
if(currentDay != gameStats.lastResetDay) {
gameStats.todayGames = 0;
gameStats.lastResetDay = currentDay;
}
gameStats.totalGames++;
gameStats.todayGames++;
gameStats.totalEarnings += 50;
if(winner == 1) gameStats.player1Wins++;
else if(winner == 2) gameStats.player2Wins++;
saveGameStatistics();
debugPrintf("📈 ISTATISTIK - Toplam=%lu, Kazanan=%d", gameStats.totalGames, winner);
}
void resetPlayer(Player* player) {
player->state = PLAYER_MENU;
player->score = 2000;
player->invincible = player->isBurning = player->hasCredit = false;
player->lastUpdateTime = player->gameStartTime = player->gameEndTime = player->lastBlinkTime = player->burnStartTime = 0;
}
void burnAction(Player* player, unsigned long currentTime) {
// LED pinleri iptal edildiği için bu kısım kaldırıldı
player->score = max(0, player->score - 200);
player->invincible = player->isBurning = true;
player->burnStartTime = currentTime;
setPixelColor(player->pixels, 255, 0, 0);
player->tft->fillScreen(ILI9341_RED);
// Burn butonuna basıldığında da 1001 LED'i aktif et
activateGameStatusLed(currentTime);
delay(2000);
player->tft->fillScreen(ILI9341_GREEN);
player->invincible = false;
drawPlayerScore(player);
}
void drawPlayerScore(Player* player) {
if(player->state != PLAYER_PLAYING) return;
player->tft->fillScreen(ILI9341_GREEN);
player->tft->setTextColor(ILI9341_BLUE);
String scoreStr = String(player->score);
int textSize = calculateTextSize(scoreStr);
player->tft->setTextSize(textSize);
int textWidth = scoreStr.length() * 18 * textSize;
player->tft->setCursor((320 - textWidth) / 2, (240 - 24 * textSize) / 2);
player->tft->print(scoreStr);
}
void drawPlayerFinalScore(Player* player) {
player->tft->fillScreen(ILI9341_BLACK);
player->tft->setTextColor(player->blinkState ? ILI9341_BLUE : ILI9341_BLACK);
player->tft->setTextSize(4);
player->tft->setCursor(70, 100);
player->tft->print(player->score);
}
int calculateTextSize(String text) {
int len = text.length();
if(len <= 3) return 6;
if(len <= 4) return 5;
if(len <= 5) return 4;
return 3;
}