Introduction: A Game of Dragons - an Arduino Led Game

I'm going to show you my game project in which mainly consist of a lot of coding. It took me a long time to get everything working, but now it finally does. I have never done anything with electronics before, nor have I much experience with coding. But I'll do my best to explain the whole code as clearly as possible and if there's anything you wanna ask or use for your own project, feel free to do so.

Step 1: Variables

////////////////////////////////VARIABLES///////////////////////////////////

//////////////////////////////Pins

int BtnP1 = 3;

int FledP1 = 5;

int LledP1 = 13;

////////////////////////////////Scores

int ScoreP1 = 2;

int CurrentLedP1 = 0;

////////////////////////////////////Buttons & Delays

int ResetBttns = 0 ;

boolean P1 = false;

boolean P1Output = false;

boolean P1Delay = false;

unsigned long int P1DelaySave = 0;

int P1DelayInterval = 400;

//////////////////////////////////////////Speed

int Speedstart = 1500;

int SpeedP1 = Speedstart;

float SpeedPercentage = 0.955;

unsigned long time;

boolean TimerActiveP1 = false;

int IntervalP1 = 0;

unsigned long int TimeSaveP1 = 0;

///////////////////////////////////////////Pause

boolean Pause = true;

//////////////////////////////////////////////////////////////////////////////////////////////////

NOTES

All variables should be quite clear, although it's important to match some to your setup;

FledP1 this responds to the first led that is pluged into pin x
LledP1 this responds to the last led that is pluged into pin x
It's important that you keep all the leds in a following order, the for loops will take care of everything inbetween those numbers.

BtnP1 this responds to the button that is plugged into pin x

If you're wondering what "unsigned long" stands for, it simply is a variable that has an large amount of bits assigned to it.

Step 2: Setup()

////////////////////////////////SETUP///////////////////////////////////

void setup() {

Serial.begin(9600);

/////////////////LED CONFIG P1

for (int LedP1 = FledP1; LedP1 <= LledP1 + 1; LedP1++) {

pinMode(LedP1,OUTPUT);

}

pinMode(BtnP1,INPUT);

}

/////////////////////////////////////////////////////////////////////////////

NOTES

nothing really amazing happening here. The for loop goes through all pins between the first led and the last, so you don't end up changing it whenever you wanna change the amount of leds

Step 3: Void CleanBoard()

////////////////////////////////CLEAN BOARDS///////////////////////////////

void cleanBoardP1() {

for (int x = FledP1; x <= LledP1; x++) {

digitalWrite(x,LOW);

}

}

/////////////////////////////////////////////////////////////////////////////////////////

NOTES

whenever this function is called all leds on the board of the first player are set to LOW. I used this so I don't have to manually set the previous one to LOW. It has worked for me really well, although there might be a problem when your Arduino decided to go through the script too fast and the leds will start to flicker.

Step 4: Void P1ButtonDelay()

////////////////////////////////BUTTON DELAYS///////////////////////////

boolean P1ButtonDelay(){

//////////////////////////Starts the delay when the button is pressed and the delay in not allready active

if ((P1 == true)&&(P1Delay==false)){

P1Delay = true;

P1Output = true;

P1DelaySave = time;

}

////////////////////////////////When active, checks if the delay has exceeded the interval

if(P1Delay == true){

if ((time-P1DelaySave) > (P1DelayInterval)){

if (ResetBttns == 1){

P1Delay = false;

}

}

}

/////////////////////////////////This comes back at the end after the loop, also see the note down here ...

if (ResetBttns == 1){

P1Output = false;

}

////////////////////////////////////When done returns true in the code

if (P1Output == true){

return true;

}

///////////////////////////////in any other cases return false

return false;

}

///////////////////////////////////////////////////////////////////////////////////////////////

NOTES

The first ridiculously complex piece of code!
Don't worry, it looks more complex than it actually is. It all basically comes down to the main idea of a manual delay and checks if it's done or not.

The ResetBttns variable can be found at the far end of the code. It makes sure the function above will be able to return "true" every time for as long as the loop is running. So it can output something from the moment that the timer is over and when the loop has ended.

Step 5: Game Systems (the Heart of Our Project)

////////////////////////////////P1 GAME SYSTEM/////////////////////////////////////

////////////////////NORMAL GAME STATE

void GameSystemP1(){

cleanBoardP1();

if (CurrentLedP1 > ScoreP1){

TimerActiveP1 = false;

CurrentLedP1 = 0;

if (ScoreP1 >= 3) {

SpeedP1 = SpeedP1 / SpeedPercentage;

ScoreP1 -= 1;

}

return;

}

/////////////////////////////////
NOTES

The current led can never be higher than the current score. Therefore, the played has not pushes the button at all, which result in a decreasing of the score.

It's important to note that when the player loses:
-the current led is set back to 0
-the current timer is reset

Except only when the score is above its minumin:
-the score decreases
-the speed increases (reversed percentage)

////////////////////////////////

////FINAL LED

if (ScoreP1 == CurrentLedP1) {

//////////Turns on the timer

if (TimerActiveP1 == false){

TimerActiveP1 = true;

IntervalP1 = SpeedP1;

TimeSaveP1 = time;

}

///////////The button was pressed at the right led

if(P1ButtonDelay() == true){

TimerActiveP1 = false;

CurrentLedP1 = 0;

SpeedP1 = SpeedP1 * SpeedPercentage;

ScoreP1 += 1;

}

////////////turn on the led

if ((time-TimeSaveP1) < (IntervalP1)){

digitalWrite((CurrenLedP1+FledP1),HIGH);

}

////////////The player did not press the button and therefore loses a round

if ((time-TimeSaveP1) > (IntervalP1)){

TimerActiveP1 = false;

CurrentLedP1 = FledP1;

if (ScoreP1 >= 3) {

SpeedP1 = SpeedP1 / SpeedPercentage;

ScoreP1 -= 1;

}

return;

}

}


//////CONTINUED LEDS

else{

/////////////////turns on the timer

if (TimerActiveP1 == false){

TimerActiveP1 = true;

IntervalP1 = SpeedP1;

TimeSaveP1 = time;

}

////////////////the player pressed the button at the wrong time

if(P1ButtonDelay() == true){

TimerActiveP1 = false;

CurrentLedP1 = 0;

if (ScoreP1 >= 3) {

SpeedP1 = SpeedP1 / SpeedPercentage;

ScoreP1 -= 1;

}

return;

}

////Normal Blink

else {

if ((time-TimeSaveP1) < (0.25*IntervalP1)){

digitalWrite((CurrenLedP1+FledP1),HIGH);

}

if ((time-TimeSaveP1) > (0.5*IntervalP1)){

digitalWrite((CurrenLedP1+FledP1),LOW);

}

}

////the player pressed the button at the right time!!!

if ((time-TimeSaveP1) > (IntervalP1)){

TimerActiveP1 = false;

CurrentLedP1 += 1;

}

}

return;

}

Step 6: Loop - Part a - Serial Monitor

////////////////////////////////LOOP//////////////////////////////////////

void loop() {

////////////////////READ SWITCHES

P1 = digitalRead(BtnP1);

time = millis();

////////////////////PRINTING

Serial.print("P1Score:");

Serial.print(ScoreP1);

Serial.print(" ");

Serial.print("P1Speed:");

Serial.print(SpeedP1);

Serial.print(" ");

Serial.print("CurrentLedP1:");

Serial.print(CurrentLedP1);

Serial.print(" ");

Serial.print("P1Bttn:");

Serial.print(P1);

Serial.print(" ");

Serial.print("BttnDelayP1:");

Serial.print(P1ButtonDelay());

Serial.print(" ");

Serial.print("BttnDelayP1Actv:");

Serial.print(P1Delay);

Serial.print(" ");

Serial.print("Time:");

Serial.print(time);

Serial.print(" ");

Serial.print("TimerActive:");

Serial.print(TimerActiveP1);

Serial.print(" ");

Serial.print("TimeSaveP1:");

Serial.print(TimeSaveP1);

Serial.print(" ");

Serial.print("IntervalP1:");

Serial.print(IntervalP1);

Serial.println();

/////////////////////////////////////

NOTES

This basically prints all important variables that change throughtout the game

Step 7: Loop - Part B

/////////////////////Pause

to Start

if (Pause == true){

digitalWrite(FledP1,HIGH);

if (P1ButtonDelay() == true){

Pause = false;

}

}

else{

/////////////////////GameSystems

GameSystemP1();

}

///////////////////////Reset BttnDelay

ResetBttns = 1;

P1ButtonDelay();

ResetBttns = 0;

////////////////////////////////END LOOP///////////////////////////////////

}

//////////////////////////////////

NOTES

When the system is not at pause perform the gamesystem.

And last but not least reset the button delay.

Step 8: The End

I hope you learned something usefull, or saw some things here that you could use for your own work feel free to do so!

I know it will be usefull to change the connected leds with a shiftregister, but I honestly haven't quite figured out how that is supposed to work out. Maybe that I'll post the result of it here one day.