HaoZhang SID: 201199702

Dependencies:   mbed

Revision:
0:45ce241d316b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu May 14 17:26:41 2020 +0000
@@ -0,0 +1,497 @@
+/*
+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
+    }    
+ }
+}