#include "pitches.h"
#include <Wire.h> // I2C程式庫
#include <LiquidCrystal_I2C.h> // LCD_I2C模組程式庫
// LCD I2C位址,默認為0x27或0x3F,依據背板的晶片不同而有差異,16、2為LCD顯示器大小。
// A4、A5的腳位為Arduino Uno 定義的I2C腳位
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int LDRpin_1 = A0; //綠
const int LDRpin_2 = A2; //黃
const int buttonPin = 9;
int buttonState = 0;
//得分的光敏電阻讀值的門檻
int score_r = 1900;
int score_r_2 = 3200; //4個光敏電阻的
int gameover_r = 800;
// notes in the melody:
int melody_score[] = {
NOTE_E4, NOTE_G4, NOTE_C5, NOTE_E5, NOTE_C5
};
int melody_over[] = {
NOTE_E4, NOTE_C4, NOTE_G3, 0, NOTE_F3, NOTE_E4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations_score[] = {
8, 8, 8, 8, 8
};
int noteDurations_over[] = {
8, 8, 4, 8, 8, 4
};
int score = 0; // 計分板分數
void setup() {
Serial.begin(9600);
pinMode(3, OUTPUT);
pinMode(8, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
// 初始化LCD
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0); // (column, row)從第一排的第三個位置開始顯示
lcd.print("Pinball Game");
lcd.setCursor(5, 1); // (column, row)從第一排的第六個位置開始顯示
lcd.print("Start");
delay(1500);
playScore();
countdown();
}
void loop() {
int sensorValue_1 = analogRead(LDRpin_1);
int sensorValue_2 = analogRead(LDRpin_2);
int gameoverValue = analogRead(A1); //感應遊戲結束
sensorValue_1 = map(sensorValue_1, 0, 1023, 0, 3069);
sensorValue_2 = map(sensorValue_2, 0, 1023, 0, 4096);
gameoverValue = map(gameoverValue, 0, 1023, 0, 2046);
Serial.println(sensorValue_1);
Serial.println(sensorValue_2);
Serial.println(gameoverValue);
Serial.println(score);
Serial.println(" ");
// 計分板
lcd.setCursor(2, 0); // (column, row)從第一排的第三個位置開始顯示
lcd.print("Pinball Game");
lcd.setCursor(2, 1); // (column, row)從第一排的第三個位置開始顯示
lcd.print("Score : ");
lcd.setCursor(10, 1); // (column, row)從第十一個位置開始顯示
lcd.print(score);
if (gameoverValue < gameover_r) { // 假設遊戲結束的條件
lcd.clear(); // 清除LCD內容
lcd.setCursor(4, 0); // 顯示 "Game Over"
lcd.print("Game Over");
lcd.setCursor(1, 1); // (column, row)從第一排的第三個位置開始顯示
lcd.print("Total Score : ");
lcd.setCursor(14, 1); // (column, row)從第十一個位置開始顯示
lcd.print(score);
playGameOver(); // 播放遊戲結束音效
showGameover();
//只要感測到就不會繼續restart
while (gameoverValue < gameover_r) {
gameoverValue = analogRead(A1); // 持續更新 gameoverValue
gameoverValue = map(gameoverValue, 0, 1023, 0, 2046); // 重新映射
Serial.println(gameoverValue);
delay(100);
}
delay(500);
restart();
}
else if (sensorValue_1 < score_r) { // 感應到的條件
digitalWrite(3, HIGH); // 燈亮
playScore();
score += 1; // 計分+1
showScore();
}else if (sensorValue_2 < score_r_2) { // 感應到的條件
digitalWrite(3, HIGH); // 燈亮
playScore();
score += 3; // 計分+3
showScore();
} else {
digitalWrite(3, LOW); // 燈滅
}
//讀取按鈕狀態
buttonState = digitalRead(buttonPin);
if(buttonState == LOW){
//digitalWrite(3, HIGH); // 燈亮
//playScore();
//score += 1; // 計分+1
//showScore();
}else {
digitalWrite(3, LOW); // 燈滅
}
delay(20); // 延遲時間調整
}
void playScore() {
for (int thisNote = 0; thisNote < 5; thisNote++) { // 修正循環次數
int noteDuration = 1000 / noteDurations_score[thisNote];
tone(8, melody_score[thisNote], noteDuration); // pin腳=8
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// 停止音調播放
noTone(8);
}
}
void playGameOver() {
for (int thisNote = 0; thisNote < 6; thisNote++) { // 修正循環次數
int noteDuration = 1000 / noteDurations_over[thisNote];
tone(8, melody_over[thisNote], noteDuration); // pin腳=8
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// 停止音調播放
noTone(8);
}
}
void restart(){
lcd.clear();
lcd.setCursor(2, 0); // (column, row)從第一排的第三個位置開始顯示
lcd.print("Pinball Game");
lcd.setCursor(5, 1); // (column, row)從第一排的第六個位置開始顯示
lcd.print("Restart");
delay(2000);
countdown();
score = 0; // 分數歸零
lcd.clear();
lcd.setCursor(2, 0); // 恢復 Pinball Game 畫面
lcd.print("Pinball Game");
lcd.setCursor(2, 1);
lcd.print("Score : ");
lcd.setCursor(10, 1);
lcd.print(score);
}
void countdown(){
lcd.clear();
lcd.setCursor(2, 0); // (column, row)從第一排的第三個位置開始顯示
lcd.print("Pinball Game");
for (int i = 1; i < 6; i++){
int j = 6 - i;
lcd.setCursor(7, 1);
lcd.print(j);
digitalWrite(3, HIGH); // 燈亮
delay(700);
digitalWrite(3, LOW); // 燈滅
delay(300);
}
}
void showScore(){
lcd.setCursor(10, 1); // (column, row)從第一排的第十一個位置開始顯示
lcd.print(score);
}
void showGameover(){
if(score < 5){
delay(1000);
lcd.setCursor(4, 0); // 顯示 "Game Over"
lcd.print("Keep it up !");
}else if (score >= 5 && score < 10){
delay(1000);
lcd.setCursor(4, 0); // 顯示 "Game Over"
lcd.print("Great job !");
}else if (score >= 10 && score < 15){
delay(1000);
lcd.setCursor(4, 0); // 顯示 "Game Over"
lcd.print("Awesome !");
}else if (score >= 15 && score < 20){
delay(1000);
lcd.setCursor(3, 0); // 顯示 "Game Over"
lcd.print("Fantastic !");
}else if (score >= 20){
delay(1000);
lcd.setCursor(0, 0); // 顯示 "Game Over"
lcd.print("You're on fire !");
}
}