#include <Adafruit_GFX.h> // 引入Adafruit GFX庫
#include <Adafruit_ILI9341.h> // 引入Adafruit ILI9341庫
#define TFT_CS 10 // 定義ILI9341晶片選擇引腳
#define TFT_RST 9 // 定義ILI9341重置引腳
#define TFT_DC 8 // 定義ILI9341數據/命令切換引腳
#define JOY_X A0 // 定義搖桿的X軸模擬輸入引腳
#define JOY_Y A1 // 定義搖桿的Y軸模擬輸入引腳
#define JOY_BUTTON 2 // 定義搖桿按鈕引腳
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); // 初始化ILI9341顯示器
int posX = 120; // 圖形的初始X座標
int posY = 160; // 圖形的初始Y座標
int prevX = 120; // 先前圖形的X座標
int prevY = 160; // 先前圖形的Y座標
int shapeSize = 20; // 圖形大小
int bulletX[50]; // 子彈的X座標陣列
int bulletY[50]; // 子彈的Y座標陣列
int bulletSpeed = 15; // 子彈速度
int bulletCount = 0; // 目前子彈數量
unsigned long lastShootTime = 0; // 上次射擊的時間
unsigned long shootInterval = 300000; // 射擊間隔(微秒)
void setup() {
tft.begin(); // 初始化顯示器
tft.setRotation(2); // 將顯示器旋轉180度以適應正方形
pinMode(JOY_BUTTON, INPUT_PULLUP); // 設置搖桿按鈕引腳為輸入,並啟用內部上拉電阻
tft.fillScreen(ILI9341_BLACK); // 用黑色填充整個屏幕
// 繪製圖形
drawShape(posX, posY, ILI9341_WHITE);
}
void loop() {
// 讀取搖桿的X和Y軸值
int joyX = analogRead(JOY_X);
int joyY = analogRead(JOY_Y);
// 將搖桿的值映射到圖形移動的範圍
int moveX = map(joyX, 0, 1023, -5, 5); // 這裡的範圍 (-5, 5) 可以根據需要調整
int moveY = map(joyY, 0, 1023, -5, 5); // 這裡的範圍 (-5, 5) 可以根據需要調整
// 更新圖形的位置
posX = constrain(posX + moveX, 0, tft.width() - shapeSize); // 考慮到圖形大小和屏幕邊界
posY = constrain(posY + moveY, 0, tft.height() - shapeSize); // 考慮到圖形大小和屏幕邊界
// 繪製新的圖形
drawShape(posX, posY, ILI9341_WHITE);
// 檢查是否可以射擊
if (micros() - lastShootTime > shootInterval && bulletCount < 50) {
// 射擊子彈
shootBullet();
// 更新射擊時間
lastShootTime = micros();
}
// 移動子彈
moveBullets();
delay(100); // 稍微延遲以避免屏幕閃爍
}
// 繪製圖形
void drawShape(int x, int y, uint16_t color) {
tft.drawRect(prevX, prevY, shapeSize, shapeSize, ILI9341_BLACK); // 清除先前的圖形
tft.drawRect(x, y, shapeSize, shapeSize, color); // 繪製空心矩形圖形
prevX = x; // 更新先前的X座標
prevY = y; // 更新先前的Y座標
}
// 射擊子彈的函數
void shootBullet() {
if (bulletCount < 50) {
// 子彈從玩家圖形的上方中心點生成
bulletX[bulletCount] = posX + shapeSize / 2;
bulletY[bulletCount] = posY + 5; // 微調位置,避免與玩家圖形重疊
bulletCount++;
}
}
// 移動子彈
void moveBullets() {
for (int i = 0; i < bulletCount; i++) {
// 如果子彈未超出屏幕,則移動子彈並繪製
if (bulletY[i] < tft.height()) {
tft.fillRect(bulletX[i], bulletY[i], 2, 5, ILI9341_BLACK); // 清除先前的子彈
bulletY[i] += bulletSpeed; // 子彈向下移動
tft.fillRect(bulletX[i], bulletY[i], 2, 5, ILI9341_WHITE); // 繪製新的子彈
} else { // 如果子彈超出屏幕,則移除子彈
bulletX[i] = bulletX[bulletCount - 1];
bulletY[i] = bulletY[bulletCount - 1];
bulletCount--;
}
}
}