#include <LiquidCrystal_PCF8574.h>
#include <Wire.h> //12c庫
#define Button 8
#define POS 15 //LCD 0~15 //CAR速度(刷新週期為200*SPEED => SPEED越小CAR移動越快)
#define OFFSET 5 //控制CAR在coordx 15外隨機生成位置的最大值
#define MAX_SPEED 10 // 設定最大速度值
int flag, up, down; //按鈕、D相關
int time, coordx_C, car2_xOffest, coordx_C2, UPDATE_CAR2, C2_Offset, time2;
int P_Offset, coordx_P, UPDATE_P, P_control; //P相關
int score;
int SPEED = 5;
LiquidCrystal_PCF8574 lcd (0x27);
//設定模組的位置為0x27
//默認位址為0x27或0x3F
void setup() {
// put your setup code here, to run once:
lcd.begin(16, 2); //這個lcd顯示16*2個字元
pinMode(Button,INPUT);
flag=0;
up= 0;
down= 0;
score= 0;
UPDATE_P= 1;
P_control= 0;
UPDATE_CAR2= 0;
time=random(SPEED*POS, SPEED*POS+ SPEED*OFFSET); //位置和time有關=> 隨機生成time
time2=random(SPEED*POS, SPEED*(POS+5)+ SPEED*OFFSET+10); //位置和time有關=> 隨機生成time
} //setup()
void loop() {
// put your main code here, to run repeatedly:
lcd.setBacklight (255); //背光0-255
time-=1;
time2-=1;
//=======================按鈕、D===============================
if(digitalRead(Button)==1)
flag = 1-flag;
else {
if(flag==0){
lcd.setCursor (0,0);
lcd.print("D");
lcd.setCursor (0,1);
lcd.print(" ");
up= 1;
down= 0;
}
if(flag==1){
lcd.setCursor (0,0);
lcd.print(" ");
lcd.setCursor (0,1);
lcd.print("D");
down= 1;
up= 0;
}
}
//=======================按鈕、D===============================
//=================CAR1===================
if(time<=SPEED*16 && time>=SPEED*(-2)){ //CAR的C位置介於 -3~15
coordx_C=time/SPEED-1;
//控制CAR前進
if(coordx_C> 0){
lcd.setCursor (coordx_C,0);
lcd.print("CAR ");
}
if (coordx_C > 0) {
// 檢查是否與CAR2重疊(擴大範圍並留有空隙)
if (coordx_C2 < coordx_C - 1 || coordx_C2 > coordx_C + 2) {
lcd.setCursor(coordx_C, 0);
lcd.print("CAR ");
}
}
//當CAR的C來到coordx=0後
if(coordx_C<=0){
if(up== 1){ //判斷是否撞到
lcd.setCursor (coordx_C,0);
lcd.clear();
lcd.print("GAME OVER!!!");
time-= SPEED*4; //Game Over後為了讓time達到重置的條件,重新開始遊戲
score= 0;
delay (2000);
lcd.clear();
}
else{ //讓CAR慢慢消失
if(coordx_C== 0){
lcd.setCursor (0,0);
lcd.print("CAR ");}
if(coordx_C== -1){
lcd.setCursor (0,0);
lcd.print("AR ");}
if(coordx_C== -2){
lcd.setCursor (0,0);
lcd.print("R ");}
if(coordx_C== -3){
lcd.setCursor (0,0);
lcd.print(" ");}
}
}
}
//=================CAR1===================
//==================P====================
if (time % SPEED == 0) {
if (UPDATE_P) {
P_Offset = (P_control % 2) ? 4 : 8; // 交替位置
coordx_P = coordx_C + P_Offset; // 確保 P 在 CAR 右側
// 確保 P 在有效範圍內
if (coordx_P < 16) {
UPDATE_P = 0; // 允許顯示 P
}
} else {
// 控制 P 前進
if (coordx_P >= 0) {
lcd.setCursor(coordx_P, 0);
lcd.print("P "); // 顯示 P
}
// 判斷是否撞到 D
if (coordx_P == 0) {
if (up == 1) {
score += 10; // 增加得分
SPEED = constrain(SPEED - 1, 1, MAX_SPEED); // 加速
if (coordx_C > 0) {
lcd.setCursor(coordx_C, 0);
lcd.print("CAR "); // 更新 CAR 顯示
}
lcd.setCursor(coordx_P, 0);
lcd.print("D "); // 顯示 D
}
UPDATE_P = 1; // 允許下一次生成 P
}
// 自動消失邏輯
if (coordx_P <= 0) { // 修改為 <= 0,確保在 P 移動過程中能夠正確消失
lcd.setCursor(coordx_P + 1, 0); // 確保清除從正確位置開始
lcd.print(" "); // 清除 P 的顯示
coordx_P = -2; // 防止再次顯示
}
// 持續向左移動
coordx_P -= 1;
}
}
//==================P====================
//=================CAR2===================
if(time2<=SPEED*16 && time2>=SPEED*(-2)){ //CAR的C位置介於 -3~15
coordx_C2=time2/SPEED-1;
//控制CAR前進
if(coordx_C2> 0){
lcd.setCursor (coordx_C2,1);
lcd.print("CAR ");
}
if (coordx_C2 > 0) {
// 檢查是否與CAR1重疊(擴大範圍並留有空隙)
if (coordx_C < coordx_C2 - 1 || coordx_C > coordx_C2 + 2) {
lcd.setCursor(coordx_C2, 1);
lcd.print("CAR ");
}
}
//當CAR的C來到coordx=0後
if(coordx_C2<=0){
if(down== 1){ //判斷是否撞到
lcd.setCursor (coordx_C2,1);
lcd.clear();
lcd.print("GAME OVER!!!");
time2-= SPEED*4; //Game Over後為了讓time達到重置的條件,重新開始遊戲
score= 0;
delay (2000);
lcd.clear();
}
else{ //讓CAR慢慢消失
if(coordx_C2== 0){
lcd.setCursor (0,1);
lcd.print("CAR ");}
if(coordx_C2== -1){
lcd.setCursor (0,1);
lcd.print("AR ");}
if(coordx_C2== -2){
lcd.setCursor (0,1);
lcd.print("R ");}
if(coordx_C2== -3){
lcd.setCursor (0,1);
lcd.print(" ");}
}
}
}
//=================CAR2===================
//=========計算分數=============
if((time%SPEED)== 0)
score++;
if(score< 10){
lcd.setCursor (15,0);
lcd.print(score);
}
else if(score< 100){
lcd.setCursor (14,0);
lcd.print(score);
}
else if(score< 1000){
lcd.setCursor (15,0);
lcd.print(score);
}
else if(score< 10000){
lcd.setCursor (15,0);
lcd.print(score);
}
//=========計算分數=============
//重置time
if (time<SPEED*(-2))
time= random(SPEED*POS, SPEED*POS+ SPEED*OFFSET);
if (time2<SPEED*(-2))
time2= random(SPEED*POS, SPEED*POS+ SPEED*OFFSET);
delay (200);
}