HaoZhang SID: 201199702

Dependencies:   mbed

main.cpp

Committer:
zh870524589
Date:
2020-05-14
Revision:
2:867fdea920c1
Parent:
0:45ce241d316b

File content as of revision 2:867fdea920c1:

/*
ELEC2645 Embedded Systems Project
School of Electronic & Electrical Engineering
University of Leeds
Name:HaoZhang
Username: el17h3z
Student ID Number:201199702
Date:14th May 2020
*/

#include "list"
#include "mbed.h"
#include "N5110.h"
#include "Gamepad.h"
#include "ETank.h"
#include "MyTank.h"
#include "Bullet.h"
#include "Map.h"
#include "time.h"
#include "string"
using namespace std;
// the levels for the game
enum LV{
    Menu,
    map_edit,
    Guide,
    Advice,
    level1,
    level2,
    level3,
    level4,
    level5,
    level6,
    level7,
    level8,
    level9,
    SHOP,
    GAME_OVER,
    Win
};

// the graph of the menu
const int menu_tank[28][28] =   
{
    {0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1},
    {0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
    {0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0},
    {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0},
    {0,0,0,0,1,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0},
    {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
    {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
    {0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0},
    {0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
    {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1},
    {0,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0},
    {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
    {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
};

DigitalIn button_A(PTB9);
N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
N5110 lcd2;  //Store map
Gamepad pad;
MyTank myTank;
Map map;
list<Bullet*>tbullet;//Store the bullet
list<ETank*>etank;//Store the ETank(enemy)
Vector2D v;

int num_etank;// num_etank: represents the number of simultaneous occurrences on the screen
int total_num;// total_num:It is the total number of ETank
int et_move;  //Computer tank's movement probability
int attack_gap;
int level_check;//for the shop to identify levels
int num_buy_check;//for the shop to identify the number that user buy
int pages = 0;// the page of guide

const int fps = 8;  
/** run the main part of game
 * @param num_etank - represents the number of simultaneous occurrences on the screen
 * @param limit - represents the number of simultaneous occurrences allowed on the screen
 * @param total_num -  total_num:It is the total number of ETank
 * @param attack_gap - attack interval
 */
void render(int &num_etank,int limit,int &total_num,int attack_gap);
/** Initialize */
void init();
/** Create the ETank
 *@param etank - the enemy's tanks
 *@param lcd - Target Screen
 *@param pad - set the tone when the tank create
 *@param num_etank - represents the number of simultaneous occurrences on the screen
 *@param num_limit - Represents the number of simultaneous occurrences allowed on the screen
 *@param total_num - A total of enemy's tanks were created
 */
void createtank(list<ETank*>&etank,N5110 &lcd,Gamepad &pad,int &num_etank,int num_limit,int &total_num);
/**the different level of the game to run
 *@param lv - the different level
 */
void play(LV &lv);
/** design the main levels of the game
 *@param s - show the current level on the screen
 *@param num_etank - represents the number of simultaneous occurrences on the screen
 *@param limit  - represents the number of simultaneous occurrences allowed on the screen
 *@param total_num -  A total of enemy's tanks were created
 *@param attack_gap - attack interval
 *@param lv - To end the game
 */
void level_design(char* s,int num_etank,int limit,int total_num,int attack_gap,LV &lv);


int main()

{   
    init(); 
    srand(time(NULL));
   
    LV lv = Menu;   
    while(1)
    {
     play(lv);
     if(lv == Guide && pages == 5)
     {
          pages = 0; 
          lv = Menu;  
     }
     if(lv == GAME_OVER)
      {       
        lcd.clear();
        lcd.printString("YOU LOSE!",2,2);
        lcd.refresh();
        wait(10.0f/fps); 
        lv = Menu; 
               
       }  
     }
 
    
}



void init()
{
    lcd.init();
    pad.init();
    
} 


void createtank(list<ETank*>&etank,N5110 &lcd,Gamepad &pad,int &num_etank,int num_limit,int &total_num)
{
    // when the number of ETank is smaller than the limit of the level,create ETank
    while(num_etank <num_limit)
    {
     ETank *et = new ETank(lcd,pad);
     etank.push_back(et);
     num_etank++;//the ETank showing in the screen increase
     total_num++;//total number increase
    }
}
  

 void render(int &num_etank,int limit,int &total_num,int attack_gap)
{
    // clear screen, re-draw and refresh
    myTank.read_input(pad);
    lcd.clear();  
    lcd = lcd2;
    myTank.draw(lcd);
    if(total_num <=15)//check if the total numbers of ETank in one level are bigger than 15 
    createtank(etank,lcd,pad,num_etank,limit,total_num);   // create the ETank
    for(list<ETank*>::iterator it =etank.begin();it!=etank.end();)
     {    
        (*it)->drawE(lcd);
        (*it)->direction(myTank);
        int et_attack = rand()%100;  //Random attack
        (*it)->attack(v,pad,lcd,myTank,tbullet,et_attack,attack_gap);
         et_move = rand()%11;
         if(et_move > 3) //posibility of moving
        (*it)->update(lcd,myTank,etank);        
         it++;
     }
    myTank.attack(tbullet,v,pad,lcd,etank,num_etank);
    myTank.update(etank);
    lcd.refresh();
    wait(1.0f/fps);
}



void level_design(char* s,int num_etank,int limit,int total_num,int attack_gap,LV &lv) 
{
    lcd.clear();
    char buffer1[14];
    sprintf(buffer1,"%s",s);
    lcd.printString(buffer1,5,1);
    lcd.refresh();
    wait(10.0f/fps);

    while(1){
     render(num_etank,limit,total_num,attack_gap);
     int HP = myTank.MT_HP(); 
     if( num_etank == 0)     
       break;      
     if(HP == 0)
     {
      lv = GAME_OVER;
      break;
     }         
    }
    
}


void play(LV &lv)  // the whole game process
{
 switch(lv)
 {
case Menu:
      pad.init();
      etank.clear();
      tbullet.clear();
      
    while(1){
      lcd.clear();
      lcd.drawSprite(25,2,28,28,(int *)menu_tank); 
      lcd.printString("TANK",1,1);
      lcd.printString("WAR",60,1);
      lcd.printString("START-- Play",10,4);
      lcd.printString("X ---  Guide",10,5);
      lcd.refresh();
      wait(5.0f/fps);
      if(pad.check_event(Gamepad::START_PRESSED)== true){
       lv = Advice;    
       break;
       }
      else if(pad.check_event(Gamepad::X_PRESSED)== true){     
       lv = Guide;  
       break;
       }
     }  
     break;
     
case Advice:
       while(1){
       lcd.clear();     
       lcd.printString("read Guide",0,0);
       lcd.printString("before game",0,1);
       lcd.printString(" A--continue",0,2);
       lcd.printString("to map edited",0,3);
       lcd.printString(" B--return",0,4);
       lcd.printString("to the menu",0,5);
       lcd.refresh();
       wait(5.0f/fps);
       if(pad.check_event(Gamepad::A_PRESSED)== true){
           lv = map_edit;
           break;
       }  
       if(pad.check_event(Gamepad::B_PRESSED)== true){
           lv = Menu;
           break;
       }   
       }
       break;
     
case map_edit:
      map.init(lcd);
      while(1){ 
      lcd.clear();  
      map.update(pad); // edit the map
      map.paddraw(lcd); 
      map.drawmap(pad,lcd);
      if(pad.check_event(Gamepad::START_PRESSED)== true)
      {
        lcd2 = lcd;// store the map in lcd2
        lv = level1;//finish edit and go to level1
        break;
      }
      lcd.refresh();
      wait(1.0f/fps); 
    } 
    break;
    
case Guide:
       while(pages == 0){
       lcd.clear();     
       lcd.printString("Tank-attack:A",0,0);
       lcd.printString("--Press A",10,1);
       lcd.printString("Tank-Move:",0,2);
       lcd.printString("--joystick ",10,3); 
       lcd.printString("Tank-HP: 3",0,4);   
       lcd.printString("  B-NEXT",30,5);
       lcd.refresh();
       wait(5.0f/fps);
        if(pad.check_event(Gamepad::B_PRESSED)== true){
          pages=1;  //flip over
          break;
        }
       }
       
       while(pages == 1){
       lcd.clear(); 
       lcd.printString("Map edit:",0,1);
       lcd.printString("You can draw",0,2);
       lcd.printString("the map before",0,3);
       lcd.printString("game starting",0,4); 
       lcd.refresh();
       wait(5.0f/fps);
        if(pad.check_event(Gamepad::B_PRESSED)== true){
          pages=2;//flip over
          break;
          }
       }
       while(pages == 2){
       lcd.clear(); 
       lcd.printString("Square Move:",0,0);   
       lcd.printString("--joystick ",10,1);  
       lcd.printString("Draw:",0,2);
       lcd.printString("--Press X",10,3); 
       lcd.printString("Finishi draw:",0,4);
       lcd.printString("--Press START",0,5);    
       lcd.refresh();
       wait(5.0f/fps);
        if(pad.check_event(Gamepad::B_PRESSED)== true){
          pages=3;//flip over
          break;
          }
        }
 
       while (pages == 3){
       lcd.clear(); 
       lcd.printString("The map drawn is",0,0);
       lcd.printString("--river",0,1);
       lcd.printString("The river:",0,2);
       lcd.printString("Stop movements",0,3);
       lcd.printString("but no effect",0,4);
       lcd.printString("to bullets",0,5);  
       lcd.refresh();
       wait(5.0f/fps);
          if(pad.check_event(Gamepad::B_PRESSED)== true){          
          pages=4;  //flip over       
          break;
          }
       }
     
       while(pages == 4){
       lcd.clear();  
       lcd.printString("SHOP:",0,0);   
       lcd.printString("Every two",0,1);
       lcd.printString("levels,you can",0,2);
       lcd.printString("go shopping",0,3);
       lcd.printString("BACK-EXIT",10,5);
       lcd.refresh();
       wait(5.0f/fps);
       if(pad.check_event(Gamepad::BACK_PRESSED)== true){
         pages = 5;//flip over
         break;
         }
      }
      
      break;
     
              
case level1:
    myTank.init(pad,lcd);
    level_design("LV1",0,2,0,17,lv);
    if(lv!=GAME_OVER)
      lv = level2; // go to level2
    wait(10.0f/fps);
    break;
    
case level2:
    level_check = 2;
    level_design("LV2",0,3,0,17,lv);
    if(lv!=GAME_OVER)
    lv = SHOP;// go to shop
    wait(10.0f/fps);
    break;    
 
case level3:
    level_design("LV3",0,3,0,16,lv);
    if(lv!=GAME_OVER)
    lv = level4;// go to level4
    wait(10.0f/fps);
    break; 

case level4:
    level_check = 4;
    level_design("LV4",0,3,0,15,lv);
    if(lv!=GAME_OVER)
    lv = SHOP;// go to shop
    wait(10.0f/fps);
    break; 
    
case level5:
    level_design("LV5",0,3,0,13,lv);
    if(lv!=GAME_OVER)
    lv = level6;// go to level6
    wait(10.0f/fps);
    break; 
    
case level6:
    level_check = 6;
    level_design("LV6",0,4,0,13,lv);
    if(lv!=GAME_OVER)
    lv = SHOP;// go to shop
    wait(10.0f/fps);
    break; 
    
case level7:
    level_design("LV7",0,5,0,13,lv);
    if(lv!=GAME_OVER)
    lv = level8;// go to level28
    wait(10.0f/fps);
    break; 
    
case level8:
    level_check = 8;
    level_design("LV8",0,5,0,10,lv);
    if(lv!=GAME_OVER)
    lv = SHOP;// go to shop
    wait(10.0f/fps);
    break; 
    
case level9:
    level_design("LV9",0,5,0,9,lv);
    if(lv!=GAME_OVER)
    lv = Win;// go to win
    wait(10.0f/fps);
    break; 

case Win:
       while(1){
       lcd.clear();     
       lcd.printString("YOU WIN!",0,0);
       lcd.printString("B--return",0,4);
       lcd.printString("to the menu",0,5);
       lcd.refresh();
       wait(5.0f/fps);
       if(pad.check_event(Gamepad::B_PRESSED)== true){
           lv = Menu;//back to the menu
           break;
       } 
       }   
       break;
           
case SHOP:  
    pad.tone(500.0,0.1);
    num_buy_check = 0;
    lcd.clear();     
    lcd.printString("-----SHOP-----",5,0);
    lcd.printString("Only pick one",0,1);  
    lcd.printString("X-attack gap-1",0,3);  
    lcd.printString("A-HP + 1",0,4);
    lcd.printString("BACK-EXIT",0,5);
    lcd.refresh(); 
    if(pad.check_event(Gamepad::X_PRESSED)== true )
    {
        myTank.attack_gap = myTank.attack_gap -1;
        num_buy_check = 1;// ensure the player can only buy one thing
    } 
    if(pad.check_event(Gamepad::A_PRESSED)== true )
       {
           if(myTank.totalHP<6)
           {
            myTank.totalHP++;
            myTank.setHP(pad);// add the HP
           }
           else
           {
           pad.leds_on();
           myTank.setHP(pad);// add the HP
           }
           num_buy_check = 1;
       }  
    if(pad.check_event(Gamepad::BACK_PRESSED)== true || num_buy_check==1)
    {
         if(level_check == 2)
         lv = level3;//go to level3
         else if(level_check == 4)
         lv = level5;//go to level5
         else if(level_check == 6)
         lv = level7;//go to level7
         else if(level_check == 8)
         lv = level9;//go to level9
    }    
 }
}