Code for the space evader game.
Dependencies: N5110 PowerControl mbed
Diff: main.cpp
- Revision:
- 0:dd6685f1343e
- Child:
- 1:225522d0dd77
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun May 10 16:48:46 2015 +0000 @@ -0,0 +1,1054 @@ +/** +@file main.cpp +@brief Header file containing functions prototypes, defines and global variables. +@brief Main code for the running of the game with external libraries of the joystick and the lcd screen +@author Dominic J. Platt +@date April 2015 +*/ +#include "mbed.h" +#include "main.h" +#include "N5110.h" //importing Craig Evans library for LCD pixel manipulation functions +#include "joystick.h" //external joystick files defined for simplification within the main file +//external variables printFlag,joystick,pollJoystick,serial and button used +//button(p18),xPot(p19),yPot(p20) used with external joystick +#include "PowerControl/PowerControl.h" +#include "PowerControl/EthernetPowerControl.h" +int main() +{ + init(); + void PHY_PowerDown(); //powerdown the ethernet interface on the Mbed system + int counter = 0;//counter to count through the timer loops + introInit(); + timer.attach(&timerExpired,0.01); + while(1) { + + if(menuMode&timerFlag) { + timerFlag = 0; + if(counter==20) { + menuSet();//runs the menu every 20 counts + } + if(soundOn) { + soundActivate(); //activates sound + } + if(counter == 20) { + counter=0;//reset the counter + } + counter++; + //timer.detach(); + //timer.attach(&timerExpired,0.01);//attaching the timer for the next frame + } else if(gameOverMode&timerFlag) { + //game over mode + timerFlag=0; + if(counter==20) { + gameOverSet();//sets the game over frame every 20 counts + } + if(soundOn) { + soundActivate(); //acitvates sound + } + if(counter == 20) { + counter=0;//reset the counter + } + counter++; + //timer.detach(); + //timer.attach(&timerExpired,0.01);//attaching the timer for the next frame + } else if(introMode&timerFlag) { + introSet(); //sets the intro frame every count + timer.detach(); + timer.attach(&timerExpired,0.01); //attaching the timer for the next frame + } else if(helpMode&timerFlag) { + timerFlag = 0; + if(buttonFlag) { + menuInit(); //if button pressed go back to the menu + } + buttonFlag = 0; + if(counter == 20) { + counter=0;//reset the counter + } + counter++; + //timer.detach(); + //timer.attach(&timerExpired,0.01); + } + + else if(highScoreMode&timerFlag) { + if(counter==20) { + timerFlag = 0; + if(buttonFlag) { + menuInit(); //if button pressed bring player back to menu + } + } + if(counter == 20) { + counter=0;//reset the counter + } + counter++; + //timer.detach(); + //timer.attach(&timerExpired,0.01); + } else if(settingsMode&timerFlag) { //runs settingsMode + timerFlag=0; + if(counter==20) { + settingsSet();//runs the setting frame + } + if(soundOn) { + soundActivate(); + } + if(counter == 20) { + counter=0;//reset the counter + } + counter++; + //timer.detach(); + //timer.attach(&timerExpired,0.01); + } else if(timerFlag&gameMode) { //game run mode + timerFlag = 0; + if(roundFlag) { + //if new round flag is set start the next round + roundFlag =0; + roundInit(); + } + if(soundOn) { + soundActivate();//activates sound + } + if(item.active) { + item.addSelf();//if item has selected add the item to the screen + } + if(speedState==0) { + //controlling the rate of movement of the players ship and asteroids depending on the speedState + if(counter == 5||counter == 10||counter == 15||counter == 20) { + if(shipExplodeFlag) { + shipExplode();//if is in explotion stage play explotion frame + } else { + //otherwise move the ship + ship.moveSelf(joystick.direction[0],joystick.direction[1]); + } + for(int i=0; i<8; i++) { + if(asteroidM[i].active) { + //move the asteroids that are active + asteroidM[i].moveSelf(); + } + } + } + } else if(speedState==1) { + if(counter == 4||counter == 8||counter == 12||counter == 16||counter == 20) { + if(shipExplodeFlag) { + shipExplode(); + } else { + ship.moveSelf(joystick.direction[0],joystick.direction[1]); + } + for(int i=0; i<8; i++) { + if(asteroidM[i].active) { + asteroidM[i].moveSelf(); + } + } + } + } else if(speedState==2) { + if(counter == 3||counter == 6||counter == 9||counter == 12||counter == 15||counter == 18||counter == 20) { + if(shipExplodeFlag) { + shipExplode(); + } else { + ship.moveSelf(joystick.direction[0],joystick.direction[1]); + } + for(int i=0; i<8; i++) { + if(asteroidM[i].active) { + asteroidM[i].moveSelf(); + } + } + } + } else if(speedState==3) { + if(counter == 2||counter == 4||counter == 6||counter == 8||counter == 10||counter == 12||counter == 14||counter == 16||counter == 18||counter == 20) { + if(shipExplodeFlag) { + shipExplode(); + } else { + ship.moveSelf(joystick.direction[0],joystick.direction[1]); + } + for(int i=0; i<8; i++) { + if(asteroidM[i].active) { + asteroidM[i].moveSelf(); + } + } + } + } + + if(buttonFlag&laserClear) { // fire button pressed + laserActivate(); + } + buttonFlag = 0; //reset the buttonFlag after everytime used + laserMove(); //move the laser depending on that which are active + check(); //checks the logic of the ships position against asteroids, asteroids against each other and walls, lasers against asteroids + if(counter ==3||counter == 6|| counter ==9||counter == 12||counter == 15||counter == 18||counter == 20) { + setScreen(); // refresh the screen once every three 'counts' + } + if(counter == 20) { + counter=0;//reset the counter + } + counter++; + //timer.detach(); + //timer.attach(&timerExpired,0.005);//timerExpired function increased rate for the game + } + sleep();// put the mbed to sleep otherwise + } +} + +void setScreen() +{ + for(int i = 0; i<84; i++) { + for(int j = 0; j<48; j++) { //loop through each element of the array + if(!(cellsCurrent==cellsBuffer)) {//if the currentCell element does not equal to the previous cell element update the display + if (cellsCurrent[j][i] == 1) { + lcd.setPixel(i,j); //set pixel if 1 + } else { + lcd.clearPixel(i,j); //clear pixel otherwise + } + cellsBuffer[j][i] = cellsCurrent[j][i]; //update the bufferArray + } + } + } + lcd.refresh(); //refreshing the screen for the new display +} +void init() +{ + lcd.init(); + debounce.start(); //start the debounce timer + buttonFlag =0; + walls = 0; // variable to declare whether asteroids can pass through walls + settingsMode =0; + speedState = 0; + roundNumber = 1; + asteroids = 0; + directionMatrix[0] = -1; // the two available matrices for our asteroids direction + directionMatrix[1] = 1; + //declares when the player is able to shoot again + laserClear = 1; + //counter to count how long a laser has been active for + laserCounter = 0; + timerFlag = 0; //timer intially 0 + laserCoolDown = 70; + rapidFire = 0; + abilityCounter = 0; + titleSelected = 0; + introMode = 1; + lcd.init(); + srand(time(NULL));//seedin the random function with the current time for more random functions + joystickButton.rise(&buttonPressed); //function called when button is pressed + serialTime.attach(&serialISR); //function called when string is sent to the mded + calibrateJoystick(); //joystick must remain still during this stage + pollJoystick.attach(&updateJoystick,1.0/10.0); //joystick checked every 10 s + lcd.setBrightness(1.0);//set the brightness to maximum as sound interfere's with each other +} +void clearArray() +{ + //clears the 'master' cell array so that all the pixels are nil + for(int i = 0; i<48; i++) { + for(int j = 0; j<84; j++) { + cellsCurrent[i][j] =0; + } + } +} +void initSound() +{ + if(sound) { + soundOn = 1; + soundCounter = 0; + buzzer = 0.01; + } +} +void soundActivate() +{ + if(sound) { + buzzer = 0.01; + if(soundCounter>19) { + soundOn = 0; + soundCounter = 0; + buzzer = 0; + //sets the sound according to which soundType is active + } else if(soundType ==1) { + buzzer.period(1/(frequency[soundCounter]));//cycles through the frequency elements to produce a increasing frequency sound + soundCounter++; + } else if(soundType ==2) { + buzzer.period(1/(frequency[19-soundCounter]));//moves backwards through the frequency elements to produce a decreasing frequency sound + soundCounter = soundCounter+2; + } else if(soundType ==3) { + buzzer.period(0.005);//high frequency sound when asteroids bounce off one another + soundCounter = soundCounter+10; + } else if(soundType ==4) { + buzzer.period(1/(frequency[19-soundCounter])); + soundCounter = soundCounter+1; + } + } +} +void iDSet() +{ + FILE *fp = fopen("/local/Highscores.csv", "r"); // open file for reading + char stringBuff[100]; //creating our stringBuff to hold the characters read from the file + if (fp == NULL) {//if file cannot be opened + perror ("Error opening file"); + for(int i = 0; i<5; i++) { + iD[i].active = 0; //deactivate the iD classes + } + return; + } else { + if ( fgets (stringBuff , 100 , fp) != NULL ) + puts (stringBuff); //sets the stringBuff to hold the characters of the fike + fclose (fp); + } + int k = 0; //integer represents which char in the file the program is at + for(int i=0; i<5 ; i++) { // 5 for loop to loop through all 5 iD objects + if(stringBuff[k]=='*') { + return; //exit loop when it reaches a '*' which is set to signify the end of the file + } + for(int j = 0; j<3; j++) { + iD[i].name[j] = stringBuff[k];//3 characters of the string buff set to the iD + k++;//increment counter + } + int scoreInt[5];//holds each digit of the score + for(int j=0; j<5; j++) { + scoreInt[j] = 0; // setting these elements to nil + } + k++;//increment counter as current character will be a ',' + int count = 0;//count to count how many digits the score has + for(int j = 0; (!(stringBuff[k]==',')); j++) { // loop while not at character ',' + scoreInt[j] = stringBuff[k]- '0';//setting the score digit to be the number selected + k++;//increment counter + count = j; + } + //sets the score according to the digits obtained and the number of digits + if(count ==1) { + iD[i].score = scoreInt[0]*10; + } else if(count==2) { + iD[i].score = scoreInt[0]*100+scoreInt[1]*10; + } else if(count==3) { + iD[i].score = scoreInt[0]*1000+scoreInt[1]*100+scoreInt[2]*10; + } else if(count ==4) { + iD[i].score = scoreInt[0]*10000+scoreInt[1]*1000+scoreInt[2]*100+scoreInt[3]*10; + } else if(count ==5) { + iD[i].score = scoreInt[0]*100000+scoreInt[1]*10000+scoreInt[2]*1000+scoreInt[3]*100+scoreInt[4]*10; + } + k++;//increment counter + for(int j = 0; (!(stringBuff[k]==',')); j++) {//for loop while character is not a ',' + iD[i].date[j] = stringBuff[k]; // sets the data characters + k++; + } + k++; + iD[i].active = 1; // iD is now active + if(stringBuff[k]=='*') { + i=5; //exit loop when '*' is reached + } + } +} + +void writeDataToFile(int score,char n1, char n2, char n3) +{ + //code idea from http://www.cplusplus.com/reference/cstdio/fgets/ + + ID playerBuff; //ID object created to hold the players attributes to write into the file + playerBuff.score = score; + playerBuff.active = 1; + sprintf(playerBuff.name,"%c%c%c",n1,n2,n3); + time_t seconds = time(NULL); // get current time + //format time into a string (time and date) + strftime(playerBuff.date,6,"%b", localtime(&seconds)); + iDSet();//gets the current players ID from the file + for(int i = 0; i<5; i++) { + //organises the current players score against the other one and shifts all iDs below downwards + if(playerBuff.score>iD[i].score) { + if(i<4) { + iD[4] = iD[3]; + } + if(i<3) { + iD[3] = iD[2]; + } + if(i<2) { + iD[2] = iD[1]; + } + if(i<1) { + iD[1] = iD[0]; + } + iD[i] = playerBuff; + i=5; //exit for loop + } + } + remove( "/local/Highscores.csv" ); //deletes the existing file + FILE *fp0 = fopen("/local/Highscores.csv", "a"); // open 'log.csv' (excel file) for appending +// creates a new file + for(int i = 0; i<5; i++) { + if(iD[i].active) { // writes the currents players iD into the file with a ',' to seperate the attributes + fprintf(fp0,"%c%c%c,%d,%s,",iD[i].name[0],iD[i].name[1],iD[i].name[2],iD[i].score,iD[i].date); // print string to file "," represents break between name and score "/" represents a new line + } + } + //writes a '*' to signify the end of the data + fprintf(fp0,"*");//marks the end of the file + fclose(fp0); // close file +} +void writeID() +{ + lcd.clear(); + //prints the column names + lcd.printString("Name",0,0); + lcd.printString("Score",26,0); + lcd.printString("Date",56,0); + //assigns the players iD from the flash drive + iDSet(); + for(int i = 0; i<5; i++) { + //printing each repective ID on the screen + if(iD[i].active) { //only if the ID is active do we want to display this + char nameString[3]; + char scoreString[5]; + sprintf(scoreString,"%d",iD[i].score); + sprintf(nameString,"%c%c%c",iD[i].name[0],iD[i].name[1],iD[i].name[2]); + lcd.printString(nameString,0,i+1); + lcd.printString(scoreString,26,i+1); + lcd.printString(iD[i].date,56,i+1); + } + } +} + +void initSpawn() +{ + int count = 0; + //defining the spawnLocations matrix + for(int j = 0; j<4; j++) { + for(int i= 0 ; i<8; i++) { + if(i==7||i==0||j==0||j==3) { + //defining the spawn locations to be along the borders of the screen + spawnLocation[count][0] = i*10; + spawnLocation[count][1] = j*10; + if(j==3) { + spawnLocation[count][1] = 42; + } + spawnLocation[count][2] = 1; + count++; + } + } + } + if(ship.position[1]<10) { + int x = ship.position[0]/10; + spawnLocation[x][2] = 0; // not available + } + if((ship.position[1]>30)) { + int x = ship.position[0]/10; + spawnLocation[x+12][2] = 0; + if(!((x+11)==11)) { + spawnLocation[x+11][2] = 0; + } + if(!((x+13)==20)) { + spawnLocation[x+13][2] = 0; + } + } + if(ship.position[0]<10) { + int x = ship.position[1]/10; + if(x==0) { + spawnLocation[0][2] = 0; + } + if(x==1) { + spawnLocation[8][2] = 0; + } + if(x==2) { + spawnLocation[10][2] = 0; + } + if(x==3) { + spawnLocation[12][2] = 0; + } + } + if(ship.position[0]>74) { + int x = ship.position[1]/10; + if(x==0) { + spawnLocation[7][2] = 0; + } + if(x==1) { + spawnLocation[9][2] = 0; + } + if(x==2) { + spawnLocation[11][2] = 0; + } + if(x==3) { + spawnLocation[19][2] = 0; + } + } +} +int getSpawnLocation() +{ + + while(1) {//while loop continues until function produces a return + int x = rand() % 20; // produces a random number 0 to 19 + if(spawnLocation[x][2]) { + //if position is available + spawnLocation[x][2] = 0;//position no longer available + return x;//position is no longer availables + } + } +} +void timerExpired() +{ + // timer function to control the frame rate, enemy speed, ship speed, laser speed + timerFlag = 1; //turn flag on +} + +Laser laserInit() //function to create a laser class with x y position sent +{ + Laser laser; //laser object created of the Laser class + laser.active = 0; // laser is not active + laser.counterFlag = 0; + for(int i =0; i< 5; i++) { + laser.shape[i] = 1; // defining the laser matrix + } + return laser; //returning the laser class +} + +void gameOverInit() +{ + //initialises variables for the gameOver screen + cSelected =0; + c1 =0; + c2 = 0; + c3 = 0; + gameMode = 0; + gameOverMode =1; + menuMode = 0; + speedState = 0; + //http://developer.mbed.org/questions/249/float-or-integer-to-char-or-string-conve/ + char scoreString[10]; + //converts score to string + sprintf(scoreString,"%d",score); + lcd.clear(); + lcd.printString("Game Over",10,0); + lcd.printString("Your score was",0,1); + //score is printed + lcd.printString(scoreString,10,2); + lcd.printString("AAA",10,4); + buttonFlag = 0; + timer.detach(); + timer.attach(&timerExpired,0.01); +} +void check() +{ + //ship position check against asteroids + for (int j = 0; j<8; j++) { + //loops through every asteroid + if((((asteroidM[j].position[0])>(ship.position[0]-5))&((asteroidM[j].position[0])<(ship.position[0]+5)) + &((asteroidM[j].position[1])>(ship.position[1]-5))&((asteroidM[j].position[1])<(ship.position[1]+5)))&asteroidM[j].active) { + //if an asteroid overlaps with a ships position + if(ship.shield) {//if ship shields are up + asteroidM[j].active = 0; + asteroidM[j].deleteSelf(); //deactivating the asteroid + asteroids--; + if(score>50) {//player looses 50 points + score = score - 50; + } else { + score = 0; + } + ship.shield =0; //shields are deactivated + ship.shieldUpdate();//updates the players shield state + initSound(); + soundType =3; + } else if((!shipExplodeFlag)&!ship.shield) { + shipExplodeFlag = 1; + explotionStage = 1; + asteroidM[j].active = 0; + asteroidM[j].deleteSelf(); + initSound(); + soundType =2; + } + } + } +// checking the asteroids position off each other so they can bounce off each other + for(int i = 0; i<8; i++) { + if(asteroidM[i].active) { //looping through all the active asteroids + for(int j = 0; j<8; j++) { + if(i==j) { //if asteroid checked is the actual asteroid of the first for loop move to the next one + j++; + } + if(asteroidM[j].active) { + if((asteroidM[i].position[0]>(asteroidM[j].position[0]-5))&(asteroidM[i].position[0]<(asteroidM[j].position[0]+5)) + &(asteroidM[i].position[1]>(asteroidM[j].position[1]-5))&(asteroidM[i].position[1]<(asteroidM[j].position[1]+5))) { + // if asteroids collide + initSound(); + soundType =3;// produce a sound + if(asteroidM[i].position[0]>asteroidM[j].position[0]) {//if asteroids x position is greater than the other move forwards + asteroidM[i].xDirection = 1; + } else if(asteroidM[i].position[0]<=asteroidM[j].position[0]) { //if asteroid is behind the other asteroid in the x direction move to the left + asteroidM[i].xDirection = -1; + } + if(asteroidM[i].position[1]>asteroidM[j].position[1]) {//if asteroid is below the other asteroid move down + asteroidM[i].yDirection = 1; + } else if(asteroidM[i].position[1]<=asteroidM[j].position[1])//if asteroid is above the other asteroid move up + asteroidM[i].yDirection = -1; + } + } + } + } + } + //checking the laser positions against the asteroids + for(int i = 0; i<4; i++) { + for (int j = 0; j<8; j++) { + if(((asteroidM[j].position[0]>(laser[i].position[0]-5))&(asteroidM[j].position[0]<(laser[i].position[0]+5)) + &(asteroidM[j].position[1]>(laser[i].position[1]-5))&(asteroidM[j].position[1]<(laser[i].position[1]+5))&asteroidM[j].active&laser[i].active)) { + //if both laser and asteroid is active and they collide inititiate destruction + initSound(); + soundType =2;//play sound + asteroidM[j].active = 0; + asteroidM[j].deleteSelf(); //deactivating the asteroid + asteroids--;//marking one less asteroid + score = score + 10;//player gains point + laser[i].active = 0; // deactiviating the laser + laser[i].deleteSelf(); + if(!(item.active||rapidFire)) { + int x = rand() %7; // 1 in 7 chance of an item drop + if(x==0) { + //puts the item to the asteroids position + item.active = 1; + item.position[0] = asteroidM[j].position[0]; + item.position[1] = asteroidM[j].position[1]; + item.addSelf(); + } + } + } + } + } + if(asteroids == 0) { + //new round when all asteroids are destroyed + roundFlag = 1; + } + if(rapidFire) { + //rapidFire enabled when user touches item + if(abilityCounter>1000) { //if the ability counter exceeds a certain number + rapidFire=0;//deactivate rapidFire + laserCoolDown = 70; //laser fire cool down set to normal + } else { + abilityCounter++; //increment counter + } + } + if((((item.position[0])>(ship.position[0]-5))&((item.position[0])<(ship.position[0]+5)) + &((item.position[1])>(ship.position[1]-5))&((item.position[1])<(ship.position[1]+5)))&item.active) { + //if ship collides with the item + //sets the laserCoolDown to be much lower for rapidFire + laserCoolDown = 22; + item.active = 0; //deactivate and remove the item from the matrix + item.deleteSelf(); + rapidFire = 1; + abilityCounter = 0;//initiates counter + } + +} + +void laserActivate() +{ + laserClear = 0; // laser is not clear to fire + if(!laser[0].active) {//if laser is not active activate this laser object + laser[0].position[0] = ship.position[0] + 5; + laser[0].position[1] = ship.position[1] + 2;//set the lasers position and activate + laser[0].active =1; //laser is now active + laser[0].counterFlag = 1; + } else if(!laser[1].active) { + laser[1].position[0] = ship.position[0] +5; + laser[1].position[1] = ship.position[1] +2; + laser[1].active = 1; + laser[1].counterFlag = 1; + } else if(!laser[2].active) { + laser[2].position[0] = ship.position[0]+5; + laser[2].position[1] = ship.position[1]+2; + laser[2].active = 1; + laser[2].counterFlag = 1; + } else if(!laser[3].active) { + laser[3].position[0] = ship.position[0]+5; + laser[3].position[1] = ship.position[1]+2; + laser[3].active = 1; + laser[3].counterFlag = 1; + } + initSound();//initiate laser sound + soundType =1; +} +void laserMove() +{ + //moves the laser if it is active + if(laser[0].active) { + laser[0].moveSelf(1); + } + if(laser[1].active) { + laser[1].moveSelf(1); + } + if(laser[2].active) { + laser[2].moveSelf(1); + } + if(laser[3].active) { + laser[3].moveSelf(1); + } + //if laser counterFlag is set, increment the laser Counter + if(laser[0].counterFlag||laser[1].counterFlag||laser[2].counterFlag||laser[3].counterFlag) { + //if the laserCounter exceeds the cooldown limit laser is clear to fire + if(laserCounter>laserCoolDown) { + laserCounter = 0; + laserClear = 1; + laser[0].counterFlag = 0; + laser[1].counterFlag = 0; + laser[2].counterFlag = 0; + laser[3].counterFlag = 0; + } + laserCounter++; + } +} +void gameStart() +{ + for(int i = 0; i<8; i++) { + asteroidM[i].active = 0; + } + item.active = 0; + clearArray(); + asteroids = 0; + roundNumber = 1; + score = 0; + menuMode =0; + gameMode =1; + highScoreMode = 0; + lcd.clear(); + clearArray(); + ship.init(); + ship.addSelf(); + item.init(); + roundFlag = 1; + gameMode = 1; + buttonFlag =0; + shipExplodeFlag = 0; + timer.detach(); + timer.attach(&timerExpired,0.005); +} +void highScoreSet() +{ + menuMode = 0; + gameMode = 0; + introMode = 0; + highScoreMode = 1; + gameOverMode = 0; + iDSet(); + writeID(); + timer.detach(); + timer.attach(&timerExpired,0.01); +} +void menuSet() +{ + //sets the option selected depending on the joystick y direction + titleSelected = titleSelected + joystick.direction[1]; + //loops around the menu + if(titleSelected>3) { + titleSelected = 0; + } else if(titleSelected<0) { + titleSelected = 3; + } + if((joystick.direction[1]==1)||(joystick.direction[1]==-1)) { + //if joystick moved initiate sound + soundType =3; + initSound(); + } + lcd.clear(); + for(int i = 0; i<84; i++) { + cellsCurrent[8][i] = 1;//draws a line under the title + } + ship.addSelf(); // adds the ship as a logo to the screen + setScreen(); // sets the screen + lcd.printString("Space Evader",0,0); //text overlayed on the screen + lcd.printString("Start Game",10,2); + lcd.printString("HighScores",10,3); + lcd.printString("Help",10,4); + lcd.printString("Settings",10,5); + lcd.printString(">",0,titleSelected+2); // array set according to which titleSelected + if(buttonFlag&(titleSelected == 0)) { + //start option selected + gameStart(); + } else if(buttonFlag&(titleSelected == 1)) { + //instruction option selected + highScoreSet(); + } else if(buttonFlag&(titleSelected == 2)) { + //instruction option selected + helpInit(); + } else if(buttonFlag&(titleSelected == 3)) { + //settings option selected + settingsInit(); + } + //setting the buttonFlag off so it is not set again until the joystick is pressed + buttonFlag = 0; +} + +void gameOverSet() +{ + if((joystick.direction[0]==1)||(joystick.direction[0]==-1)||(joystick.direction[1]==1)||(joystick.direction[1]==-1)) { + //sound activate when joystick moved + initSound(); + soundType =3; + } + char scoreString[10]; //stores the score + sprintf(scoreString,"%d",score);//converts the users score from an int to a string + char alphabet [27] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; //alphabet matrix defined + cSelected = cSelected +joystick.direction[0]; //character selected moved depending on the joystick + if(cSelected>2) { //loops through the characters selected at the boundaries + cSelected = 0; + } else if(cSelected <0) { + cSelected = 2; + }//sets the character selected depending to the one chosen + if(cSelected ==0) { + c1 = c1+ joystick.direction[1]; + if(c1>25) { + c1 = 0; + } + if(c1<0) { + c1 = 25; + } + } + if(cSelected ==1) { + c2 = c2+joystick.direction[1]; + if(c2>25) { + c2 = 0; + } + if(c2<0) { + c2 = 25; + } + } + if(cSelected ==2) { + c3 = c3 + joystick.direction[1]; + if(c3>25) { + c3 = 0; + } + if(c3<0) { + c3 = 25; + } + } + char name[3]; + //converts the name chars into a string + sprintf(name,"%c%c%c",alphabet[c1],alphabet[c2],alphabet[c3]); + lcd.clear(); + //sets the characters + lcd.printString("Game Over",10,0); + lcd.printString("Your score was",0,1); + lcd.printString(scoreString,25,2); + lcd.printString(name,25,4); + for(int i = 0; i<5; i++) { + ///draws a line under the selected char + lcd.setPixel(25+i+cSelected*6,40); + } + lcd.refresh(); + if(buttonFlag) { + //if button is pressed write the players ID to the drive + writeDataToFile(score,alphabet[c1],alphabet[c2],alphabet[c3]); + //open the menu + menuInit(); + } + //reset flag + buttonFlag = 0; +} +void helpInit() +{ + //clear the array + clearArray(); + //clear the lcd + lcd.clear(); + //initialise the spawn position, although spawn positions are not needed this function is required to initialise an asteroid object + initSpawn(); + ship.init(); + asteroidM[0].init(); + item.init(); + menuMode = 0; + gameOverMode = 0; + helpMode =1; + gameOverMode =0; + highScoreMode =0; + //adding the asteroid, ship and item objects to the screen + ship.position[0] = 0; + ship.position[1] = 0; + ship.addSelf(); + ship.shield = 0; + ship.shieldUpdate(); + ship.position[0] = 0; + ship.position[1] = 8; + ship.addSelf(); + asteroidM[0].position[0] = 0; + asteroidM[0].position[1] = 16; + asteroidM[0].addSelf(); + item.position[0] = 0; + item.position[1] = 24; + item.addSelf(); + setScreen();//setting the matrix + lcd.printString("Player ship",10,0); //adding text to label the objects + lcd.printString("Vulnerable",10,1); + lcd.printString("Asteroid",10,2); + lcd.printString("Rapid fire",10,3); + lcd.printString("Avoid and kill",0,4); + lcd.printString("the asteroids",0,5); + timer.detach(); + timer.attach(&timerExpired,0.01); +} +void menuInit() +{ + clearArray(); + ship.init(); + ship.position[0] = 75; + ship.position[1] = 2; + ship.addSelf(); + setScreen(); + lcd.printString("Space Evader",0,0); + lcd.printString("Start Game",10,2); + lcd.printString("HighScores",10,3); + lcd.printString("Help",10,4); + lcd.printString("Settings",10,5); + settingsMode = 0; + gameOverMode = 0; + gameMode = 0; + menuMode = 1; + introMode = 0; + helpMode = 0; + buttonFlag =0; + timer.detach(); + timer.attach(&timerExpired,0.01); +} +void introInit() +{ + introCounter= 0; + introMode =1; + settingsMode = 0; + gameOverMode = 0; + gameMode = 0; + menuMode = 0; + helpMode = 0; + buttonFlag = 0; + timer.detach(); + timer.attach(&timerExpired,0.01); +} +void introSet() //intro mode frame set +{ + if(introCounter<=100) { + //play this for first 100 frames + lcd.printString("Dominic Platt",0,0); + lcd.printString("Presents...",12,1); + } + if(introCounter==100) { + //initialise and set ship + ship.init(); + ship.position[0] = 0; + ship.position[1] =34; + ship.addSelf(); + } + if(introCounter>100&introCounter<180) { + //move ship for next 80 frames + ship.moveSelf(1,0); + setScreen(); + lcd.printString("Space Evader",5,0); + + } + if(introCounter==180||buttonFlag) { // if timer up or button pressed + //starts menu + ship.deleteSelf(); + menuInit(); + } + introCounter++; //introCounter +} +void roundInit() +{ + //initialises a round + if(roundNumber>8) { + roundNumber = 1; // reset the roundNumber + if(speedState<4) { + speedState++;//increases the speed of the game if it hasn't exceeded its max value + } + ship.shield=1; // regenerate shields when new round initiates + ship.shieldUpdate(); + } + initSpawn(); // initialises spawn positions + for(int i = 0; i<roundNumber; i++) { + asteroidM[i].init();//initiates asteroids equal to the round number + asteroidM[i].active = 1; + asteroids++; // add one to the counter + } + roundNumber++; //increment roundNumber +} +void shipExplode() +{ + //sets the explotionn frame of the ship + ship.destroySelf(explotionStage); + explotionStage++;//increment the explotionStage + if(explotionStage>12) { + //explotion finished gameOverScreenSet + shipExplodeFlag = 0; + gameOverInit(); + } +} +void settingsSet() +{ + //sets the title selected with the joystick + titleSelected = titleSelected + joystick.direction[1]; + if(titleSelected>3) { + titleSelected = 0; + } else if(titleSelected<0) { + titleSelected = 3; + } + if((joystick.direction[1]==1)||(joystick.direction[1]==-1)) { + soundType =3; //sound when joystick moved + initSound(); + } + lcd.clear(); + lcd.printString("Sound",7,0); + lcd.printString("On",45,0); + lcd.printString("Off",65,0); + if(sound) {//sets the marker depending on whether sound is on or not + lcd.printString(" ",59,0); + lcd.printString("-",39,0); + } else { + lcd.printString(" ",39,0); + lcd.printString("-",59,0); + } + lcd.printString("Speed",7,1); + char myChar[8]; + sprintf(myChar,"%dx",1+speedState); //speed marked + lcd.printString(myChar,60,1); + lcd.printString("Walls",7,2); + lcd.printString(">",0,titleSelected); //selector depending on option selected + char bufferDate[14]; //presents the time and date + char bufferTime[14]; + lcd.printString("Back",7,3); + time_t seconds = time(NULL); // get current time + //format time into a string (time and date) + strftime(bufferDate,14,"%D", localtime(&seconds)); + strftime(bufferTime,14,"%T", localtime(&seconds)); + lcd.printString(bufferDate,7,4); + lcd.printString(bufferTime,7,5); + if(buttonFlag&(titleSelected == 0)) { + sound = !sound; + } else if(buttonFlag&(titleSelected == 1)) { + //increments the speed counter if that option is selected + speedState++; + if(speedState>3) { + //reset speedState if to high + speedState=0; + } + } else if(buttonFlag&(titleSelected == 3)) { + //back to menu + menuInit(); + } else if(buttonFlag&(titleSelected == 2)) { + //turn on/off the walls + walls = !walls; + } + if(walls) {//presents whether the walls are active + lcd.printString("On",50,2); + } else { + lcd.printString("Off",50,2); + } + //reset the button flag + buttonFlag = 0; +} +void settingsInit() +{ + //initialises the setting screen + menuMode = 0; + settingsMode = 1; + titleSelected = 0; + buttonFlag =0; + settingsSet(); + timer.detach(); + timer.attach(&timerExpired,0.01); +} +void serialISR() +{ + //sets UNIX time + set_time(1430595271); +} +void buttonPressed() // toggle direction in ISR +{ + if(debounce.read_ms()>150) {//only set flag 150 ms after the last flag was set to filter out the 'bounces' + //buttonFlag set when button is pressed + buttonFlag = 1; + debounce.reset();//reset the debounce timer + } +} \ No newline at end of file