/*
Whac_A_Mole_v1.0.0
By WT040
*/
#include "Wire.h"
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_7segment matrix1 = Adafruit_7segment();
Adafruit_7segment matrix2 = Adafruit_7segment();
#define debounceTime 10
//declare potmeter controls
#define potmeterVolume 0
#define potmeterGameLevel 1
//declare amp power pin
#define ampPower 32
//declare buttons
#define btn1Pin 22
#define btn2Pin 24
#define btn3Pin 26
#define btn4Pin 28
#define btn5Pin 30
byte btnArray[] = {
btn1Pin,
btn2Pin,
btn3Pin,
btn4Pin,
btn5Pin
};
#define btn1 0 // for using the btn array
#define btn2 1 // for using the btn array
#define btn3 2 // for using the btn array
#define btn4 3 // for using the btn array
#define btn5 4 // for using the btn array
//declare button leds
#define btnLed1Pin 9
#define btnLed2Pin 10
#define btnLed3Pin 11
#define btnLed4Pin 12
#define btnLed5Pin 13
byte btnLedArray[] = {
btnLed1Pin,
btnLed2Pin,
btnLed3Pin,
btnLed4Pin,
btnLed5Pin
};
#define btnLed1 0 // for using the btn array
#define btnLed2 1 // for using the btn array
#define btnLed3 2 // for using the btn array
#define btnLed4 3 // for using the btn array
#define btnLed5 4 // for using the btn array
//declare audio fx digitals
#define fx0TriggerPin 29
#define fx1TriggerPin 31
#define fx2TriggerPin 33
#define fx3TriggerPin 35
#define fx4TriggerPin 37
#define fx5TriggerPin 39
#define fx6TriggerPin 41
#define fx7TriggerPin 43
#define fx8TriggerPin 45
#define fx9TriggerPin 47
#define fx10TriggerPin 49
#define fxVolUpPin 51
#define fxVolDnPin 53
byte fxTriggerArray[] = {
fx0TriggerPin,
fx1TriggerPin,
fx2TriggerPin,
fx3TriggerPin,
fx4TriggerPin,
fx5TriggerPin,
fx6TriggerPin,
fx7TriggerPin,
fx8TriggerPin,
fx9TriggerPin,
fx10TriggerPin
};
byte fxVolumeArray[] = {
fxVolUpPin,
fxVolDnPin
};
#define fx0Trigger 0 // for using the btn array
#define fx1Trigger 1 // for using the btn array
#define fx2Trigger 2 // for using the btn array
#define fx3Trigger 3 // for using the btn array
#define fx4Trigger 4 // for using the btn array
#define fx5Trigger 5 // for using the btn array
#define fx6Trigger 6 // for using the btn array
#define fx7Trigger 7 // for using the btn array
#define fx8Trigger 8 // for using the btn array
#define fx9Trigger 9 // for using the btn array
#define fx10Trigger 10 // for using the btn array
#define fxVolUp 0 // for using the btn array
#define fxVolDn 1 // for using the btn array
signed int currentPlayingSound = -1;
byte btnPressed[5], ledState[5];
//blink led
unsigned long previousMillisLedBlink = 0; //for blinking led
#define intervalLedBlink 750
//
//game start sequence
unsigned long previousMillisGameStarting = 0;
#define intervalCountDown 1000
byte gameStartCountDown;
//
//game steps
unsigned long previousMillisGameStep = 0;
int gameStepLength = 0; //length of an individual step
int gameStepBtn = 0; //the button that's need to be pushed
//
int valPotmeterVolume = 0;
int volume = 0;
int actualVolume = 35; //volume of the adafruit fx board
int valPotmeterGameLevel = 0;
int gameLevel;
int currentScore;
int highScore;
int highScoreAddr = 1;
byte activeBtn;
bool debug; //enable debug or not
byte wackAMoleState; //state of the game
bool SystemInitialized = false;
#define stateUnknown 0
#define waitForStart 1
#define starting 2
#define running 3
#define gameOver 4
#define stopped 5
void setup()
{
Serial.begin(9600);
//init amp power pin
pinMode(ampPower, OUTPUT);
digitalWrite(ampPower, LOW);
//init btn pins
for (int Pin = 0; Pin < 5; Pin++) {
pinMode(btnArray[Pin], INPUT);
}
//init btn led pins
for (int Pin = 0; Pin < 5; Pin++) {
pinMode(btnLedArray[Pin], OUTPUT);
}
//init btn fx pins
for (int Pin = 0; Pin < 11; Pin++) {
pinMode(fxTriggerArray[Pin], OUTPUT);
digitalWrite(fxTriggerArray[Pin], HIGH);
}
//init btn fx volume pins
for (int Pin = 0; Pin < 2; Pin++) {
pinMode(fxVolumeArray[Pin], OUTPUT);
digitalWrite(fxVolumeArray[Pin], HIGH);
}
matrix1.begin(0x70);
matrix2.begin(0x71);
while (!eeprom_is_ready()); // Wait for EEPROM to be ready
cli();
highScore = eeprom_read_word((uint16_t*)(gameLevel * 2));
sei();
matrix1.print(0);
matrix1.writeDisplay();
matrix2.print(0);
matrix2.writeDisplay();
initializeSystem();
}
void loop()
{
checkButtonInputs(); // when we check the switches we'll get the current state
readVolumePotmeter();
if (wackAMoleState == waitForStart) {
playSound(fx0Trigger);
if (btnPressed[btn4]) {
wackAMoleState = starting;
}
readGameLevelPotmeter();
ledBlinkStart();
}
if (wackAMoleState == starting) {
startGame();
}
if (wackAMoleState == running) {
playSound(fx1Trigger);
checkNextGameStep();
}
}
void checkNextGameStep() {
unsigned long currentMillisGameStep = millis();
int amountOfButtonPresses = 0;
for (int btn = 0; btn < 5; btn++) {
if (btnPressed[btn]) {
amountOfButtonPresses++;
}
}
if (previousMillisGameStep == 0) {
previousMillisGameStep = currentMillisGameStep;
digitalWrite(btnLedArray[btnLed4], LOW);
randomSeed(analogRead(2));
gameStepBtn = random(0, 5);
gameStepLength = random(3000 / gameLevel, 5000 / gameLevel);
digitalWrite(btnLedArray[gameStepBtn], HIGH); //light up new button light
}
if ((currentMillisGameStep - previousMillisGameStep >= gameStepLength) || (amountOfButtonPresses > 1) ||
(amountOfButtonPresses == 1) && !btnPressed[gameStepBtn]) {
//Game over...
playSound(fx2Trigger);
wackAMoleState = gameOver;
previousMillisGameStep = 0;
for (int counter = 0; counter < 5; counter++) {
analogWrite(btnLedArray[counter], 255);
}
for (int brightness = 255; brightness > 0; brightness--) {
analogWrite(btnLedArray[btnLed1], brightness);
analogWrite(btnLedArray[btnLed2], brightness);
analogWrite(btnLedArray[btnLed3], brightness);
analogWrite(btnLedArray[btnLed4], brightness);
analogWrite(btnLedArray[btnLed5], brightness);
delay(10);
}
analogWrite(btnLedArray[btnLed1], 0);
analogWrite(btnLedArray[btnLed2], 0);
analogWrite(btnLedArray[btnLed3], 0);
analogWrite(btnLedArray[btnLed4], 0);
analogWrite(btnLedArray[btnLed5], 0);
Serial.println("Game OVer");
if (currentScore > highScore) {
while (!eeprom_is_ready()); // Wait for EEPROM to be ready
cli();
eeprom_write_word((uint16_t*)(gameLevel * 2), currentScore); // Let's initialize our value into EEPROM
sei();
}
int counter = 0;
do
{
delay(1);
checkButtonInputs();
counter++;
} while ((counter < 1000) && !btnPressed[btn1] && !btnPressed[btn2 && !btnPressed[btn3] &&
!btnPressed[btn4] && !btnPressed[btn5]]);//wait for the release of the button
matrix1.print(0);
matrix1.writeDisplay();
wackAMoleState = waitForStart;
}
else if (btnPressed[gameStepBtn] && (amountOfButtonPresses == 1)) {
digitalWrite(btnLedArray[gameStepBtn], LOW); //turn off led previous button
int counter = 0;
do
{
delay(1);
checkButtonInputs();
counter++;
} while ((counter < 1000) && btnPressed[gameStepBtn]);//wait for the release of the button
previousMillisGameStep = currentMillisGameStep;
int tempStepBtn = 0;
do
{
tempStepBtn = random(0, 5);
gameStepLength = random(3000 / gameLevel, 5000 / gameLevel);
} while (gameStepBtn == tempStepBtn);
gameStepBtn = tempStepBtn;
digitalWrite(btnLedArray[gameStepBtn], HIGH); //light up new button light
currentScore++;
matrix1.print(currentScore);
matrix1.writeDisplay();
if (currentScore > highScore) {
matrix2.print(currentScore);
matrix2.writeDisplay();
}
}
}
void ledBlinkStart() //blink a led without delay
{
unsigned long currentMillisLedBlink = millis();
if (currentMillisLedBlink - previousMillisLedBlink >= intervalLedBlink) {
previousMillisLedBlink = currentMillisLedBlink;
if (ledState[0] == LOW) {
ledState[0] = HIGH;
}
else {
ledState[0] = LOW;
}
digitalWrite(btnLedArray[btnLed4], ledState[0]); //green led/button
}
}
void startGame() //start sequence of the game itself
{
unsigned long currentMillisGameStarting = millis();
digitalWrite(btnLedArray[btnLed4], 0); //turn green led/button off
currentScore = 0;
if (gameStartCountDown == 0) {
playSound(fx3Trigger);
previousMillisGameStarting = millis();
gameStartCountDown = 4;
delay(300);
matrix1.print(gameStartCountDown, DEC);
matrix1.writeDisplay();
}
if (currentMillisGameStarting - previousMillisGameStarting >= intervalCountDown) {
previousMillisGameStarting = currentMillisGameStarting;
if (gameStartCountDown > 0) {
gameStartCountDown--;
matrix1.print(gameStartCountDown, DEC);
matrix1.writeDisplay();
if (gameStartCountDown == 0) {
wackAMoleState = running;
}
}
}
}
void initializeSystem()
{
//add init code here...
digitalWrite(btnLedArray[btnLed1], HIGH);
delay(75);
digitalWrite(btnLedArray[btnLed2], HIGH);
delay(75);
digitalWrite(btnLedArray[btnLed3], HIGH);
delay(75);
digitalWrite(btnLedArray[btnLed4], HIGH);
delay(75);
digitalWrite(btnLedArray[btnLed5], HIGH);
delay(1000);
digitalWrite(btnLedArray[btnLed5], LOW);
delay(75);
digitalWrite(btnLedArray[btnLed4], LOW);
delay(75);
digitalWrite(btnLedArray[btnLed3], LOW);
delay(75);
digitalWrite(btnLedArray[btnLed2], LOW);
delay(75);
digitalWrite(btnLedArray[btnLed1], LOW);
delay(1000);
debug = true;
wackAMoleState = waitForStart;
initVolume();
if (actualVolume > 0) {
enableAmpPower(true);
}
}
void checkButtonInputs() //check for button changes
{
static byte previousstate[5];
static byte currentstate[5];
static long lasttime;
byte index;
//debounce
if ((lasttime + debounceTime) > millis()) {
return;
}
lasttime = millis();
//
for (index = 0; index < 5; index++) {
currentstate[index] = digitalRead(btnArray[index]); // read the button
if (currentstate[index] != btnPressed[index]) {
if ((btnPressed[index] == HIGH) && (currentstate[index] == LOW)) {
if (debug) {
Serial.print("button released: ");
Serial.println(index + 1);
}
btnPressed[index] = 0;
}
if ((btnPressed[index] == LOW) && (currentstate[index] == HIGH)) {
if (debug) {
Serial.print("button pressed: ");
Serial.println(index + 1);
}
btnPressed[index] = 1;
}
}
}
}
void initVolume()
{
valPotmeterVolume = (analogRead(potmeterVolume) / 30);
if (actualVolume > valPotmeterVolume) {
do {
digitalWrite(fxVolumeArray[fxVolDn], LOW);
actualVolume--;
delay(20);
digitalWrite(fxVolumeArray[fxVolDn], HIGH);
delay(20);
} while (actualVolume > valPotmeterVolume);
}
else if (actualVolume < valPotmeterVolume) {
do {
digitalWrite(fxVolumeArray[fxVolUp], LOW);
actualVolume++;
delay(20);
digitalWrite(fxVolumeArray[fxVolUp], HIGH);
delay(20);
} while (actualVolume < valPotmeterVolume);
}
}
void readVolumePotmeter()
{
valPotmeterVolume = (analogRead(potmeterVolume) / 30);
if (actualVolume > valPotmeterVolume) {
digitalWrite(fxVolumeArray[fxVolDn], LOW);
actualVolume--;
delay(40);
digitalWrite(fxVolumeArray[fxVolDn], HIGH);
if (actualVolume == 0) {
enableAmpPower(false);
}
}
else if (actualVolume < valPotmeterVolume) {
digitalWrite(fxVolumeArray[fxVolUp], LOW);
if (actualVolume == 0) {
enableAmpPower(true);
}
actualVolume++;
delay(40);
digitalWrite(fxVolumeArray[fxVolUp], HIGH);
}
}
void readGameLevelPotmeter()
{
valPotmeterGameLevel = analogRead(potmeterGameLevel);
if (valPotmeterGameLevel < 102) {
gameLevel = 1;
}
else if (valPotmeterGameLevel < 204) {
gameLevel = 2;
}
else if (valPotmeterGameLevel < 306) {
gameLevel = 3;
}
else if (valPotmeterGameLevel < 408) {
gameLevel = 4;
}
else if (valPotmeterGameLevel < 510) {
gameLevel = 5;
}
else if (valPotmeterGameLevel < 612) {
gameLevel = 6;
}
else if (valPotmeterGameLevel < 714) {
gameLevel = 7;
}
else if (valPotmeterGameLevel < 816) {
gameLevel = 8;
}
else if (valPotmeterGameLevel < 918) {
gameLevel = 9;
}
else {
gameLevel = 10;
}
matrix1.print(gameLevel);
matrix1.writeDisplay();
while (!eeprom_is_ready()); // Wait for EEPROM to be ready
cli();
highScore = eeprom_read_word((uint16_t*)(gameLevel * 2));
sei();
if (highScore > -1) {
matrix2.print(highScore);
}
else {
matrix2.print(0);
}
matrix2.writeDisplay();
}
void playSound(int sound)
{
if (currentPlayingSound != sound) {
for (int counter = 0; counter < 11; counter++) {
digitalWrite(fxTriggerArray[counter], HIGH);
}
digitalWrite(fxTriggerArray[sound], LOW);
currentPlayingSound = sound;
}
}
void enableAmpPower(bool state)
{
digitalWrite(ampPower, state);
}
Comments
Please log in or sign up to comment.