Code for the space evader game.

Dependencies:   N5110 PowerControl mbed

Revision:
0:dd6685f1343e
Child:
1:225522d0dd77
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Sun May 10 16:48:46 2015 +0000
@@ -0,0 +1,743 @@
+/**
+@file main.h
+@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 "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" // power control header files
+
+LocalFileSystem local("local"); // create local filesystem
+/**
+@namespace serialTime
+@brief serial data used to declare the program to set the time
+*/
+Serial serialTime (USBTX,USBRX);
+/**
+@brief Initialises the programs variables, the joystick initialisation and calibration, the LCD initialisation, button interrupts, serial interrupts, seeds the rand() function from time and sets the lcd brightness
+*/
+void init();
+/**
+@namespace buzzer
+@brief pwm output to control the piezo buzzer
+*/
+PwmOut buzzer(p21);
+//! an array of different frequencies for control of the buzzer
+float frequency[20] = {50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,900,950,1000,1050};;
+//!declares whether sound is turned on
+bool soundOn;
+//! how many 'frames' the sound has been active for
+int soundCounter;
+//!Declares the sound type played through the pwm
+int soundType;
+//!declares whether sound is active
+bool sound =1;
+/**
+@brief Activates the PWM for the buzzer and sets sound to be on
+*/
+void initSound();
+/**
+@brief manipulates the buzzer PWM frequency for different sounds depending on the soundType variable. This variable is global due new sounds overriding older sounds.
+*/
+void soundActivate();
+
+/**
+@namespace lcd
+@brief The lcd instance and the pins connected to it
+*/
+N5110 lcd(p7,p8,p9,p10,p11,p13,p26); // pwm for led backlight
+
+//!The 'master' matrix which holds all of the pixel values on our lcd screen
+//!Array to be modified by functions
+bool cellsCurrent[48][84];
+//!Buffer array to store the LCDs previous state
+//!Supplies information to decide whether a pixel needs to be changed or not
+bool cellsBuffer[48][84];
+/**
+@brief Clears the cellCurrent ‘master’ array, all elements set to 0.
+*/
+void clearArray();
+//! The matrix shape which holds the ship pixels
+bool playerShape1[5][5] = {0,1,1,1,0,
+                          1,1,1,0,0,
+                          0,1,1,1,1,
+                          1,1,1,0,0,
+                          0,1,1,1,0
+                         };
+//! The matrix shape which holds the ship pixels
+bool playerShape2[5][5] = {0,1,1,0,0,
+                          1,1,0,0,0,
+                          0,1,1,1,1,
+                          1,1,0,0,0,
+                          0,1,1,0,0
+                         };
+int explotionStage;
+bool explotion1[5][5] = {0,0,0,0,0,
+                        0,0,1,0,0,
+                        0,1,0,1,0,
+                        0,0,1,0,0,
+                        0,0,0,0,0
+                       };
+bool explotion2[5][5] = {0,0,1,0,0,
+                        0,0,1,0,0,
+                        1,1,0,1,1,
+                        0,0,1,0,0,
+                        0,0,1,0,0
+                       };
+bool explotion3[5][5] = {0,0,1,0,0,
+                        0,0,0,0,0,
+                        1,0,0,0,1,
+                        0,0,0,0,0,
+                        0,0,1,0,0
+                       };
+bool itemShape[5][5] = { 0,0,1,0,0,
+                        0,0,1,0,0,
+                        1,1,1,1,1,
+                        0,0,1,0,0,
+                        0,0,1,0,0
+                      };
+//!Variable to store which round the user is on
+int roundNumber;
+//!Number of asteroids active on screen
+int asteroids;
+//!variable to declare that our ship is in the explotion stage
+int shipExplodeFlag;
+/**
+@brief Runs the destroySelf function from the player class and switches to the game over screen when explosion has finished.
+*/
+void shipExplode();
+/**
+@brief array of spawn coordinates
+@brief spawnLocation[i][j] where i represents the number assigned to the coordinate location and j hold 3 elements and represents the x,y position and whether it is active
+*/
+int spawnLocation[32][3];
+/**
+Initiates the spawn locations for asteroids and marks the segment that the player is within as occupied.
+*/
+void initSpawn();
+/**
+@brief Gets a random spawn location for the asteroid to spawn. Once the position is given to an asteroid that position is marked as occupied. If a position given is already occupied then another random number is generated until an available position is given.
+*/
+int getSpawnLocation();
+/**
+@brief To be used with rand() function so that an asteroids movement is randomised
+*/
+int directionMatrix[2];
+/**
+@brief asteroid's pixel array within a 5x5 array
+*/
+bool asteroidShape[5][5] = {0,0,1,0,0,
+                            0,1,1,1,0,
+                            1,1,1,1,1,
+                            0,1,1,1,0,
+                            0,0,1,0,0
+                           };
+/**
+@brief Declares new laser can be fired
+*/
+bool laserClear;
+/**
+@brief Declares how many 'frames' it takes until a new laser can be fired
+*/
+int laserCoolDown;
+/**
+@brief Declares whether the rapid fire power up has been activated
+*/
+bool rapidFire;
+/**
+@brief Declares how many 'frames' the abilityCounter has been active for
+*/
+int abilityCounter;
+/**
+@brief Counts how many moves a laser has been active for
+*/
+int laserCounter;
+/**
+@brief Activates an available laser object if the laserClearFlag is activated.
+*/
+void laserActivate();
+/**
+@brief Moves any active lasers and increments a laser cool down if laser is not clear to fire again.
+*/
+void laserMove();
+/**
+@brief timer variable to count through the frame rates
+*/
+Ticker timer;
+/**
+@brief timer variable to count how long since last buttonFlag was set
+@brief used to prevent button bounce problem
+*/
+Timer debounce;
+/**
+@brief Flag to control the timer loops
+*/
+int timerFlag;
+/**
+@brief Function called every time a specified amount of time has passed for the menu modes this is set every 0.01s but in game mode it is set to 0.005s as fast logic is required. Controls the frame rate, enemy speed, player speed and laser speed primarily.
+*/
+void timerExpired();
+/**
+@brief Sets screen according to the current matrix enabled. If the element is one set the pixel, if the element is 0 clear the pixel. The new array is compared with the last array so that any pixels which are the same as before are not set or cleared unnecessarily. 
+*/
+void setScreen();
+/**
+@brief Checks the asteroid against laser positions and removes them if they touch , Player positions against asteroids and shields down or game over if this happens, asteroids position against each other and alter the direction so they bounce and checks if the asteroids collide with a boundary if walls are active then asteroid bounces off wall if not the asteroid appears on opposite end of screen.
+*/
+void check();
+/**
+@brief declares the program is in the game mode
+*/
+bool gameMode;
+/**
+@brief score gained by the user
+*/
+int score;
+/**
+@brief declares the program is in the menu mode
+*/
+bool menuMode;
+/**
+@brief Flag to trigger next round
+*/
+bool roundFlag;
+/**
+@brief function to initialise the next round and spawn the required number of asteroids. If round has surpassed 8 then speed is turned up, the rounds restart from one and shields of the player are restored.
+*/
+void roundInit();
+/**
+@brief Initialises the game mode, clearing array, LCD screen, variables, initialisation of classes and adding to the array.
+*/
+void gameStart();
+/**
+@brief Initialises the menu mode by initialising variables and clearing array.
+*/
+void menuInit();
+/**
+@brief Runs the menu frame, the options, the selector and the title.
+*/
+void menuSet();
+/**
+@brief declares which option on the menu the user is currently selecting
+*/
+int titleSelected;
+/**
+@brief declares gameOver mode screen
+*/
+bool gameOverMode;
+
+/**
+Initialises the gameOverScreen, displaying text and the players score.
+An integer to string converter process is used taken from http://developer.mbed.org/questions/249/float-or-integer-to-char-or-string-conve/
+*/
+void gameOverInit();
+/**
+@brief User can scroll through 3 characters and change them to present their own ID. Saves player ID to flash in descending score order when user selects if the score is within the top 5.
+*/
+void gameOverSet();
+/**
+@brief counts how many 'frames' the intro screen has been active for
+*/
+int introCounter;
+/**
+@brief declares game is in intro mode
+*/
+bool introMode;
+/**
+@brief Initialises the variables and clears screen for the introduction mode.
+*/
+void introInit();
+/**
+@brief Sets the introduction screen including the title and the ship animation.
+*/
+void introSet();
+/**
+@brief variable to declare that the highscore mode is active
+*/
+int highScoreMode;
+/**
+@brief Sets the high score mode reads the data from the flash drive and displays the top 5 users score, name and date.
+*/
+void highScoreSet();
+/**
+@brief declares the helpMode option is open
+*/
+int helpMode;
+/**
+@brief Initialises the variables, objects and clears the screen for the help mode and presents them onto the screen along with informative text.
+*/
+void helpInit();
+/**
+@brief declares setting mode is active
+*/
+bool settingsMode;
+/**
+@brief Initialises the variables, objects and clears the screen for the help mode and presents them onto the screen along with informative text.
+*/
+void settingsInit();
+/**
+@brief Sets the setting screen – Including the text and the selector and allows the user to change the options of speed, whether walls are active and toggle the sound. Time is also displayed.
+*/
+void settingsSet();
+/**
+@brief declares whether walls for the asteroid are active or not
+*/
+bool walls;
+/**
+@brief declares what speed state the game is within
+*/
+int speedState;
+/**
+@brief ID class defining the attributes of a Players name, score, the date they achieved this score and whether this Player is active
+@brief This is read from the flash drive
+*/
+class ID
+{
+public:
+/**
+declares if the object is active
+*/
+    bool active;
+    /**
+    ID score
+*/
+    int score;
+    /**
+    ID name string
+*/
+    char name[3];
+     /**
+    ID date string
+    */
+    char date[3];
+};
+/**
+@brief instance of our ID class
+*/
+ID iD1;
+/**
+@brief instance of our ID class
+*/
+ID iD2;
+/**
+@brief instance of our ID class
+*/
+ID iD3;
+/**
+@brief instance of our ID class
+*/
+ID iD4;
+/**
+@brief instance of our ID class
+*/
+ID iD5;
+/**
+@brief iD matrix of our ID objects
+*/
+ID iD[5] = {iD1,iD2,iD3,iD4,iD5};
+/**
+@brief Decodes the flash drive saved files and assigns the ID objects values.
+*/
+void iDSet();
+/**
+Compares the current players ID (the score just gained) against the ones on the flash drive and organises them as the top 5. 
+Flash drive file is deleted and a new file with the newly organised players ID is set.
+Code idea taken from http://www.cplusplus.com/reference/cstdio/fgets/
+@param score - score of the player
+@param n1 - first character of the players name
+@param n2 - second character of the players name
+@param n3 - third character of the players name
+@brief taking the players name and score this organises their score against the current players and writes the ids in score descending order
+*/
+void writeDataToFile(int score,char n1, char n2, char n3);
+/**
+@brief declares which character is selected on the screen
+*/
+int cSelected;
+/**
+@brief first character option for the user to change
+*/
+int c1;
+/**
+@brief second character option for the user to change
+*/
+int c2;
+/**
+@brief third character option for the user to change
+*/
+int c3;
+/**
+@brief read the players ID to the the flash drive and assigns the values to our ID objects
+@brief player IDs are displayed on the LCD screen
+*/
+void writeID();
+/**
+@brief Calls this function when data sent to mbed, which sets the time
+*/
+void serialISR();
+/**
+@brief flag set when button is pressed
+*/
+int buttonFlag;
+/**
+@brief Function is called when rising edge on button input, sets a buttonFlag to signal the button has been pressed.
+@brief prevents button bouncing with debounce timer, so that flag is not set again if it was only called 150 ms ago
+*/
+void buttonPressed();
+/**
+@brief Item class with properties and functions
+*/
+class Item
+{
+public:
+    /**
+    declares whether item is active
+    */
+    bool active;
+    /**
+    declares items pixel shape
+    */
+    bool shape[5][5];
+    /**
+     declares x,y coordinates of the item
+    */
+    int position[2];
+    /**
+     adds the item shape to the matrix
+    */
+    void addSelf() { //adding the shape to the array
+        for(int i = 0; i<5; i++) {
+            for(int j = 0; j<5; j++) { // for loop cycling through each element pf the array
+                cellsCurrent[position[1]+j][position[0]+i] = shape[j][i]; // setting the respective pixels
+            }
+        }
+    }
+    /**
+    deletes the item shape from the matrix
+    */
+    void deleteSelf() { // deleting the shape from the array
+        for(int i = 0; i<5; i++) {
+            for(int j =0; j<5; j++) { // for loop cycling through each element of the array
+                cellsCurrent[j+position[1]][i+position[0]] =0; // deleting the respective pixels
+            }
+        }
+    }
+    /**
+    initialises the item object
+    */
+    void init() {
+        active =0;
+        for(int i=0; i <5; i++) {
+            for(int j=0; j<5; j++) { //defining the ship array
+                shape[j][i] = itemShape[j][i];
+            }
+        }
+    }
+};
+/**
+An instance of the Item class created
+*/
+Item item;
+/**
+Our player class for the players ship defined
+*/
+class Player
+{
+    /**
+    \class player
+    Player class which is our blueprint of the players ship
+    class functions and variables are here
+    */
+public:
+    /**Array defining our Player's shape 
+    */
+    bool shape[5][5];
+    ///array defining our Player's position
+    int position[2];
+    ///declares whether the players shields are up
+    bool shield;
+    ///adding the current Player to the master matrix
+    void addSelf() { //adding the shape to the array
+        for(int i = 0; i<5; i++) {
+            for(int j = 0; j<5; j++) { // for loop cycling through each element pf the array
+                cellsCurrent[position[1]+j][position[0]+i] = shape[j][i]; // setting the respective pixels
+            }
+        }
+    }
+    ///deleting the current Player to the master matrix
+    void deleteSelf() { // deleting the shape from the array
+        for(int i = 0; i<5; i++) {
+            for(int j =0; j<5; j++) { // for loop cycling through each element of the array
+                cellsCurrent[j+position[1]][i+position[0]] =0; // deleting the respective pixels
+            }
+        }
+    }
+    ///Moves the player’s position on the matrix, boundaries are built into this function. 
+    ///This function deletes the player shape from the array, changes its position and adds the shape back to the array.
+    ///@param int x Declares the amount of position movement in the x direction in pixels
+    ///@param int y Declares the amount of position movement in the y direction in pixel
+    void moveSelf(int x, int y) { //moving the shape, x defines whether up down y defines left right
+        deleteSelf(); //deletes the shape the the array
+        if((position[0]+x < 79)&(position[0]+x>=0)) { // if within the x bounds of the screen
+            position[0] = position[0] + x; //changes the x position
+        }
+        if((position[1]+y<43)&(position[1]+y>=0)) { // if within the y bounds of the screen
+            position[1] = position[1] + y; //changes the y position
+        }
+        addSelf(); // adds object according to the new position
+    }
+    /**
+    @brief exploding frames for the ship
+    @param explotionState Which stage of the explotion the ship is at
+    */
+    void destroySelf(int explotionState) {
+        deleteSelf();
+        for(int i=0; i<5; i++) {
+            for(int j=0; j<5; j++) {
+                if(explotionState>0&explotionState<4) {
+                    shape[j][i] = explotion1[j][i];
+                } else if (explotionState>3&explotionState<8) {
+                    shape[j][i] = explotion2[j][i];
+                } else if (explotionState>7) {
+                    shape[j][i] = explotion3[j][i];
+                } else {
+                    shape[j][i] = 0;
+                }
+            }
+        }
+        addSelf();
+    }
+    /**
+    updates the players shield appearance depending on its value
+    */
+    void shieldUpdate() { //1 for pushing shields up 0 for putting them down
+        for(int i=0; i <5; i++) {
+            for(int j=0; j<5; j++) { //defining the ship array
+                if(shield) {
+                    shape[j][i] = playerShape1[j][i];
+                }//shields up
+                else {
+                    shape[j][i] = playerShape2[j][i];
+                } //shields down
+            }
+        }
+    }
+    /** Initialise player properties
+    */
+    void init() {
+        position[0] = 0;
+        position[1] = 20; //position sent to the centre of the screen
+        shield = 1;
+        shieldUpdate();
+        //addSelf(); //adding ship to the matrix
+    }
+};
+/**
+Player class instance
+*/
+Player ship;
+
+/**
+asteroid class defined
+*/
+class asteroid
+{
+    //defining our asteroid template class
+public: //our entity class is public
+    /**
+    declares that asteroid is active
+    */
+    bool active; //declaring whether the asteroid is active or not
+    /**
+    shape array holding the pixels for the asteroid
+    */
+    bool shape[5][5]; // shape array to hold the pixel data
+    /**
+    @brief 2 element array to hold the x,y position of the asteroid
+    */
+    int position[2]; // 2 element array to hold x,y components of the entities position
+    /**
+    @brief Declares the yDirection the asteroid
+    */
+    int yDirection;
+    /**
+    @brief Declares the xDirection the asteroid
+    */
+    int xDirection; // directon variables to store which direction the asteroid is moving
+    /**
+    @brief adds the asteroid object to the current matrix
+    */
+    void addSelf() { //adding the shape to the array
+        for(int i = 0; i<5; i++) {
+            for(int j = 0; j<5; j++) { // for loop cycling through each element pf the array
+                cellsCurrent[position[1]+j][position[0]+i] = shape[j][i]; // setting the respective pixels
+            }
+        }
+    }
+    /**
+    @brief removes the asteroid object to the current matrix
+    */
+    void deleteSelf() { // deleting the shape from the array
+        for(int i = 0; i<5; i++) {
+            for(int j =0; j<5; j++) { // for loop cycling through each element of the array
+                cellsCurrent[j+position[1]][i+position[0]] =0; // deleting the respective pixels
+            }
+        }
+    }
+    /**
+    @brief moves the asteroid object to the current matrix
+    */
+    void moveSelf() { //moving the shape, x defines whether up down y defines left right
+        deleteSelf(); //deletes the shape the the array
+        if((position[0]+xDirection < 79)&(position[0]+xDirection>0)) { // if within the x bounds of the screen
+            position[0] = position[0] + xDirection; //changes the x position
+        } else if(walls) {
+            soundType =3;
+            initSound();
+            xDirection = -xDirection;
+            position[0] = position[0] + xDirection; //changes the x position
+        } else {
+            if(position[0]<=0) {
+                position[0] = 79;
+            } else {
+                position[0] = 0;
+            }
+        }
+        if((position[1]+yDirection<43)&(position[1]+yDirection>0)) { // if within the y bounds of the screen
+            position[1] = position[1] + yDirection; //changes the y position
+        } else if(walls) {
+            soundType =3;
+            initSound();
+            yDirection = -yDirection;
+            position[1] = position[1] + yDirection;
+        } else {
+            if(position[1]<=0) {
+                position[1] = 43;
+            } else {
+                position[1] = 0;
+            }
+        }
+        addSelf(); // adds object according to the new position
+    }
+    /**
+    @brief initialises the properties of our asteroid object
+    */
+    void init() {
+        int x = getSpawnLocation();
+        position[0] = spawnLocation[x][0];
+        position[1] = spawnLocation[x][1]; //position defined
+        xDirection = directionMatrix[rand() % 2]; // direction chosen randomly to be + or - 1 using the directionMatrix
+        yDirection = directionMatrix[rand() % 2];
+        active = 0;
+        for(int i=0; i <5; i++) {
+            for(int j=0; j<5; j++) { //defining the asteroid array
+                shape[j][i] = asteroidShape[j][i];
+            }
+        }
+    }
+};
+///instance of our asteroid class
+asteroid asteroid1;
+///instance of our asteroid class
+asteroid asteroid2;
+///instance of our asteroid class
+asteroid asteroid3;
+///instance of our asteroid class
+asteroid asteroid4;
+///instance of our asteroid class
+asteroid asteroid5;
+///instance of our asteroid class
+asteroid asteroid6;
+///instance of our asteroid class
+asteroid asteroid7;
+///instance of our asteroid class
+asteroid asteroid8;
+
+///array holding all the asteroid objects
+asteroid asteroidM[8] = {asteroid1,asteroid2,asteroid3,asteroid4,asteroid5,asteroid6,asteroid7,asteroid8};
+/**
+@brief Laser position, active, pixel data, counterFlag variables
+*/
+class Laser
+{
+    //defining our laser class
+public: //our laser class is public
+    /**
+    @brief shape 1D array to hold the pixel data
+    */
+    bool shape[5]; // shape array to hold the pixel data
+    /**
+    @brief 2 element array to hold x,y components of the laser position
+    */
+    int position[2]; // 2 element array to hold x,y components of the laser position
+    /**
+    @brief declares the laser is active
+    */
+    bool active; //declares whether the particular laser is active
+    /**
+    @brief declares the laserCounter to start counting to trigger the laserClear variables
+    */
+    bool counterFlag; //declares the laserCounter to start counting to trigger the laserClear variables
+    /**
+    @brief adds the laser object to the current matrix
+    */
+    void addSelf() { //adding the shape to the array
+        for(int i = 0; i<5; i++) {
+            // for loop cycling through each element pf the array
+            cellsCurrent[position[1]][position[0]+i] = shape[i]; // setting the respective pixels
+        }
+    }
+    /**
+    @brief removes the laser object to the current matrix
+    */
+    void deleteSelf() { // deleting the shape from the array
+        for(int i = 0; i<5; i++) {
+            // for loop cycling through each element of the array
+            cellsCurrent[position[1]][i+position[0]] =0; // deleting the respective pixels
+        }
+    }
+    /**
+    @brief moves the laser object to the current matrix
+    @param x - decleares whether the laser is moving forwards or backwards
+    */
+    void moveSelf(int x) { //moving the laser y defines left right
+        deleteSelf(); //deletes the shape from the array
+        if((position[0]+x < 79)&(position[0]+x>0)) { // if within the x bounds of the screen
+            position[0] = position[0] + x; //changes the x position
+            addSelf(); // adds object according to the new position
+        } else { // if out of bounds deactivate the laser
+            active = 0;
+        }
+    }
+};
+/**
+@brief initialises the laser properties
+*/
+Laser laserInit();
+/**
+@brief laser object
+*/
+Laser laser1 = laserInit();
+/**
+@brief laser object
+*/
+Laser laser2 = laserInit();
+/**
+@brief laser object
+*/
+Laser laser3 = laserInit();
+/**
+@brief laser object
+*/
+Laser laser4  = laserInit();
+/**
+@brief laser object matrix
+*/
+Laser laser[4]  = {laser1,laser2,laser3,laser4};
\ No newline at end of file