#include<LedControl.h>
#include <TimerOne.h>
#include "pitch.h"
#include <LiquidCrystal_I2C.h>
#define VERT_PIN A0
#define HORZ_PIN A1
#define SEL_PIN 2
#define device_num 3
#define module_num 3
#define SPEAKER_PIN 6
#define Mis_Max 3
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
LedControl lc[module_num] = {
LedControl(12, 11, 10, device_num),
LedControl(12, 11, 9, device_num),
LedControl(12, 11, 8, device_num)
};
int x = 1; //col初始位置
int mis[22][2] = {}; //飛彈儲存陣列
int num = 0; //飛彈彈夾數量
int mon = -1;
int count = 0;
int count1 = 0;
int sc = 0;
int time = 30;
bool move = false;
bool right = false;
bool left = false;
bool reset = false;
const int NUM_NOTES = 24;
const int W_NUM_NOTES = 5;
const int melody[] = { // 開場音樂
659, 659, 659, 523, 659, 783, 880, 698, 698, 659, 587, 523,
659, 659, 659, 523, 659, 783, 880, 698, 698, 659, 587, 523
};
const int W_melody[] = { // 勝利音樂
777, 988, 1109, 1175, 1319,
};
const int L_melody[] = { // 失敗音樂
880, 783, 698, 587, 523
};
const int note[] = { // 音符長度陣列
8, 8, 4, 8, 8, 4, 2, 8, 8, 8, 8, 4, 8, 8, 4, 8, 8, 4, 2, 8, 8, 8, 8, 4
};
const int W_note[] = {
4, 8, 4, 2, 4
};
const int L_note[] = {
8, 4, 4, 2, 2
};
byte plane[] = { //飛機
0b00000001,
0b00000011,
0b00000001,
0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000,
};
byte temp[] = {
0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000,
}; //暫存飛機圖形器
void setup() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
{
lc[i].shutdown(j, false); // 關閉省電模式
lc[i].setIntensity(j, 0); // 設定亮度為 0 (介於0~15之間)
lc[i].clearDisplay(j); // 清除螢幕
}
}
for (int i = 0; i < device_num * 3 - 2; i++) {
mis[i][0] = -1;
}
pinMode(VERT_PIN, INPUT);
pinMode(HORZ_PIN, INPUT);
pinMode(SEL_PIN, INPUT_PULLUP);//設置上拉電阻
Serial.begin(9600);
lcd.init();
lcd.backlight();
Timer1.initialize(50000);
Timer1.attachInterrupt(missle);
for (int i = 0; i < NUM_NOTES; i++) {
int noteDuration = 1000 / note[i];
tone(SPEAKER_PIN, melody[i], noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(SPEAKER_PIN);
}
_plane();
attachInterrupt(digitalPinToInterrupt(SEL_PIN), fire, FALLING);
}
void monster() {
if (mon == -1)
mon = 14;
lc[0].setLed(mon / 8, 0, mon % 8, 1);
lc[0].setLed(mon / 8, 1, mon % 8 - 1, 1);
lc[0].setLed(mon / 8, 1, mon % 8, 1);
lc[0].setLed(mon / 8, 1, mon % 8 + 1, 1);
lc[0].setLed(mon / 8, 2, mon % 8, 1);
if (random(10) % 2 == 1) //往右
{
if (mon > 1)
{
lc[0].setLed((mon + 1 ) / 8, 0, (mon + 1) % 8 - 1, 0); //左邊暗
lc[0].setLed((mon + 1 ) / 8, 1, (mon + 1) % 8, 0);
lc[0].setLed((mon + 1 ) / 8, 2, (mon + 1) % 8 - 1, 0);
mon--;
lc[0].setLed(mon / 8, 0, mon % 8, 1); //右邊亮
lc[0].setLed(mon / 8, 1, (mon) % 8 - 1, 1);
lc[0].setLed(mon / 8, 2, mon % 8, 1);
}
lc[0].setLed(1, 0, 7, 0);
lc[0].setLed(1, 2, 7, 0);
lc[0].setLed(0, 0, 7, 0);
lc[0].setLed(0, 2, 7, 0);
if (mon == 15) {
lc[0].setLed(1, 0, 7, 1);
lc[0].setLed(1, 1, 7, 1);
lc[0].setLed(1, 2, 7, 1);
}
if (mon == 7) {
lc[0].setLed(0, 0, 7, 1);
lc[0].setLed(0, 2, 7, 1);
lc[0].setLed(0, 1, 7, 1);
}
}
else //往左
{
if (mon < 22)
{
lc[0].setLed(mon / 8, 0, mon % 8, 0); //右邊暗
lc[0].setLed(mon / 8, 1, (mon) % 8 - 1, 0);
lc[0].setLed(mon / 8, 2, mon % 8, 0);
mon++;
lc[0].setLed((mon + 1) / 8, 0, (mon + 1) % 8 - 1, 1); //左邊亮
lc[0].setLed((mon + 1) / 8, 1, (mon + 1) % 8, 1);
lc[0].setLed((mon + 1) / 8, 2, (mon + 1) % 8 - 1, 1);
}
if (mon == 15) {
lc[0].setLed(1, 0, 7, 1);
lc[0].setLed(1, 1, 7, 1);
lc[0].setLed(1, 2, 7, 1);
}
if (mon == 7) {
lc[0].setLed(0, 0, 7, 1);
lc[0].setLed(0, 2, 7, 1);
lc[0].setLed(0, 1, 7, 1);
}
}
showlcd();
}
void planemove() {
int vert = analogRead(VERT_PIN);
int horz = analogRead(HORZ_PIN);
if (horz > 600) { //向左
x++;
left = true;
if (x >= 23) {
x = 22;
left = false;
}
if (left == true) {
move = true;
temp[1] = plane[23];
for (int i = 22; i >= 0 ; i--) {
plane[i + 1] = plane[i] ;
}
plane[0] = temp[1];
left = false;
}
}
if (horz < 400) { //向右
x--;
right = true;
if (x <= 0) {
x = 1;
right = false;
}
if (right == true) {
move = true;
temp[0] = plane[0];
for (int i = 0; i <= 22 ; i++) {
plane[i] = plane[i + 1];
}
plane[23] = temp[0];
right = false;
}
}
if (move == true) {
_plane();
move = false;
}
}
void missle() {
count ++;
count1 ++;
planemove();
for (int i = 0; i < Mis_Max ; i++) {
lc[mis[i][0] / 8].setLed(mis[i][1] / 8, mis[i][0] % 8, mis[i][1] % 8, 0);
if (mis[i][0] > -1) {
mis[i][0]--;//飛彈往上
}
lc[mis[i][0] / 8].setLed(mis[i][1] / 8, mis[i][0] % 8, mis[i][1] % 8, 1);
}
if (mis[num][0] == 1 && (mis[num][1] == mon || mis[num][1] == mon - 1 || mis[num][1] == mon + 1) )
{
mis[num][0] = -1;
tone(SPEAKER_PIN, d5, 30);
mon_off();
for (int i = 0; i < 50; i++) {
mon_on();
}
for (int i = 0; i < 50; i++) {
mon_off();
}
for (int i = 0; i < 50; i++) {
mon_on();
}
mon_off();
mon = random(22);
sc++;
}
}
void mon_on() {
lc[0].setLed(mon / 8, 0, mon % 8, 1);
lc[0].setLed(mon / 8, 1, mon % 8 - 1, 1);
lc[0].setLed(mon / 8, 1, mon % 8, 1);
lc[0].setLed(mon / 8, 1, mon % 8 + 1, 1);
lc[0].setLed(mon / 8, 2, mon % 8, 1);
}
void mon_off() {
lc[0].setLed(mon / 8, 0, mon % 8, 0);
lc[0].setLed(mon / 8, 1, mon % 8 - 1, 0);
lc[0].setLed(mon / 8, 1, mon % 8, 0);
lc[0].setLed(mon / 8, 1, mon % 8 + 1, 0);
lc[0].setLed(mon / 8, 2, mon % 8, 0);
}
void fire() {
if (num < Mis_Max - 1 && mis[num + 1][0] <= -1) {
num++;
mis[num][0] = 21;
mis[num][1] = x;
tone(SPEAKER_PIN, d5s, 30);
lc[ mis[num][0] / 8].setLed(mis[num][1] / 8, mis[num][0] % 8, mis[num][1] % 8, 1);
}
else if (num >= Mis_Max - 2 && mis[0][0] <= -1 ) {
num = 0;
mis[num][0] = 21;
mis[num][1] = x;
tone(SPEAKER_PIN, d5s, 30);
lc[mis[num][0] / 8].setLed(mis[num][1] / 8, mis[num][0] % 8, mis[num][1] % 8, 1);
}
lc[0].setLed(0, 1, 7, 0);
lc[0].setLed(1, 1, 7, 0);
}
void _plane() {//顯示飛機
for (int i = 0; i < 24; i++) {
lc[2].setColumn(i / 8, i % 8, plane[i]);
}
}
void showlcd() {
lcd.setCursor(0, 0);
lcd.print("Your Score:");
lcd.print(sc);
lcd.setCursor(0, 1);
lcd.print("Time left:");
if (time >= 10)
lcd.print(time);
else if (time < 10 ) {
lcd.print("0");
lcd.print(time);
}
}
void Win() {
lcd.clear();
for (int i = 0; i < 8; i++) {
lcd.clear();
lcd.setCursor(i, 0);
lcd.print("YOU WIN!!");
delay(120);
}
sc = 0;
reset = true;
time = 30;
for (int i = 0; i < W_NUM_NOTES; i++) {
int Duration = 1000 / W_note[i];
tone(SPEAKER_PIN, W_melody[i], Duration);
int pause = Duration * 1.30;
delay(pause);
noTone(SPEAKER_PIN);
}
lcd.clear();
}
void Lose() {
lcd.clear();
for (int i = 0; i < 7; i++) {
lcd.clear();
lcd.setCursor(i, 0);
lcd.print("YOU LOSE!!");
delay(120);
}
sc = 0;
reset = true;
time = 30;
for (int i = 0; i < W_NUM_NOTES ; i++) {
int Duration = 1000 / L_note[i];
tone(SPEAKER_PIN, L_melody[i], Duration);
int pause = Duration * 1.30;
delay(pause);
noTone(SPEAKER_PIN);
}
lcd.clear();
}
void loop() {
if (count > random(6, 16)) {
monster();
count = 0;
}
if (count1 > 20) {
time--;
count1 = 0;
}
if (reset == false) {
if (sc >= 5 )
Win();
if (time <= 0 && sc < 5)
Lose();
reset = false;
}
}