#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define BUTTON_1 7
#define BUTTON_2 6
#define BUTTON_3 5
#define BUTTON_4 4
#define BUZZER 11
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
int playerScore = 0;
bool gameStarted = false;
unsigned long lastUpdate = 0;
int blockSize = 40; // 方塊大小
int gameSpeed = 500; // 方塊掉落速度,根據難度設置
// 遊戲界面上的方塊表示,0表示空白,1表示白色方塊,2表示黑色方塊
int blocks[5][4] = {{0}};
enum GameMode {
SINGLE_PLAYER,
DOUBLE_PLAYER
};
enum Difficulty {
EASY,
HARD
};
GameMode selectedMode;
Difficulty selectedDifficulty;
void setup() {
// 初始化設定
Serial.begin(9600);
tft.begin();
tft.setRotation(3);
// 初始化按鈕
for (int i = BUTTON_1; i <= BUTTON_4; i++) {
pinMode(i, INPUT_PULLUP);
}
pinMode(BUZZER, OUTPUT);
// 顯示標題畫面
displayTitleScreen();
}
void loop() {
if (!gameStarted) {
// 判斷是否按下開始遊戲或選擇模式的按鈕
if (digitalRead(BUTTON_1) == LOW) {
selectModeAndDifficulty();
}
if (digitalRead(BUTTON_2) == LOW) {
startGame();
}
} else {
// 遊戲進行中
updateGame();
handleButtonPress();
checkGameOver();
}
}
void selectModeAndDifficulty() {
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 50);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Select Mode:");
tft.println("1. Single Player");
tft.println("2. Double Player");
while (true) {
if (digitalRead(BUTTON_1) == LOW) {
selectedMode = SINGLE_PLAYER;
break;
} else if (digitalRead(BUTTON_2) == LOW) {
selectedMode = DOUBLE_PLAYER;
break;
}
}
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 50);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Select Difficulty:");
tft.println("1. Easy");
tft.println("2. Hard");
while (true) {
if (digitalRead(BUTTON_1) == LOW) {
selectedDifficulty = EASY;
gameSpeed = 700; // 容易難度方塊掉落速度較慢
break;
} else if (digitalRead(BUTTON_2) == LOW) {
selectedDifficulty = HARD;
gameSpeed = 300; // 困難難度方塊掉落速度較快
break;
}
}
// 開始遊戲
startGame();
}
void startGame() {
// 重置遊戲狀態
gameStarted = true;
playerScore = 0;
// 初始化方塊
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
blocks[i][j] = 0; // 初始化方塊為空
}
}
// 在頂部生成方塊
generateBlocks();
// 清除屏幕並顯示遊戲界面
tft.fillScreen(ILI9341_WHITE);
displayGameScene();
}
void updateGame() {
// 更新方塊的位置
unsigned long currentTime = millis();
if (currentTime - lastUpdate >= gameSpeed) { // 控制方塊的移動速度
lastUpdate = currentTime;
// 向下移動方塊
for (int row = 4; row > 0; row--) {
for (int col = 0; col < 4; col++) {
blocks[row][col] = blocks[row - 1][col];
}
}
// 在頂部生成新方塊
generateBlocks();
// 更新遊戲界面
displayGameScene();
}
}
void generateBlocks() {
// 在頂部生成新方塊
int colorBlockPosition = random(0, 4); // 隨機選擇一個位置生成黑色方塊
for (int col = 0; col < 4; col++) {
if (col == colorBlockPosition) {
blocks[0][col] = 2; // 使用 2 表示黑色方塊
} else {
blocks[0][col] = 1; // 使用 1 表示白色方塊
}
}
}
void handleButtonPress() {
// 檢查玩家的操作
for (int col = 0; col < 4; col++) {
if (digitalRead(col + BUTTON_1) == LOW) {
// 玩家按下按鈕對應的列
if (blocks[4][col] == 1) {
// 玩家碰到白色方塊
gameOver();
} else if (blocks[4][col] == 2) {
// 玩家成功點擊黑色方塊
playerScore++;
playSuccessSound();
// 清除方塊
blocks[4][col] = 0;
displayGameScene();
}
}
}
}
void checkGameOver() {
// 檢查是否遊戲結束
for (int col = 0; col < 4; col++) {
if (blocks[4][col] == 1) {
// 玩家碰到白色方塊
gameOver();
}
}
}
void gameOver() {
// 遊戲結束
gameStarted = false;
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(50, 100);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Game Over");
displayScore();
delay(5000); // 顯示分數 5 秒鐘後返回標題畫面
displayTitleScreen();
}
void displayTitleScreen() {
// 顯示標題畫面
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(20, 50);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Don't Tap The White Tile");
tft.setTextSize(1);
tft.setCursor(20, 100);
tft.println("Press button 5 to select mode");
tft.println("Press button 6 to start");
}
void displayGameScene() {
// 顯示遊戲界面
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 4; col++) {
if (blocks[row][col] == 0) {
tft.fillRect(col * blockSize, row * blockSize, blockSize, blockSize, ILI9341_WHITE);
} else if (blocks[row][col] == 1) {
tft.fillRect(col * blockSize, row * blockSize, blockSize, blockSize, ILI9341_WHITE);
} else {
tft.fillRect(col * blockSize, row * blockSize, blockSize, blockSize, ILI9341_BLACK);
}
}
}
// 在螢幕下方绘制一条黑色线条
int screenBottomY = tft.height(); // 螢幕底部位置
int lineWidth = tft.width(); // 螢幕的宽度
int lineHeight = 5; // 線條的高度
// 绘制一条黑色的水平线
tft.fillRect(0, screenBottomY - lineHeight, lineWidth, lineHeight, ILI9341_BLACK);
}
void displayScore() {
// 顯示玩家的分數
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.print("Score: ");
tft.println(playerScore);
}
void playSuccessSound() {
// 播放成功音效
tone(BUZZER, 1000, 200);
}