HaoZhang SID: 201199702

Dependencies:   mbed

Revision:
0:45ce241d316b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tank/MyTank.cpp	Thu May 14 17:26:41 2020 +0000
@@ -0,0 +1,327 @@
+#include "MyTank.h"
+
+
+// four different direction of Tank
+const int boom[5][5] =   
+{
+    {1,0,1,0,1},
+    {0,1,1,1,0},
+    {1,1,1,1,1},
+    {0,1,1,1,0},
+    {1,0,1,0,1},
+};
+
+// four direction of mytank
+const int run_up[5][5] =   
+{
+    {1,0,1,0,1},
+    {1,0,1,0,1},
+    {1,1,1,1,1},
+    {1,1,1,1,1},
+    {1,1,1,1,1},
+};
+
+const int run_down[5][5] =   
+{
+    {1,1,1,1,1},
+    {1,1,1,1,1},
+    {1,1,1,1,1},
+    {1,0,1,0,1},
+    {1,0,1,0,1},
+};
+const int run_left[5][5] =   
+{
+    {1,1,1,1,1},
+    {0,0,1,1,1},
+    {1,1,1,1,1},
+    {0,0,1,1,1},
+    {1,1,1,1,1},
+};
+const int run_right[5][5] =   
+{
+    {1,1,1,1,1},
+    {1,1,1,0,0},
+    {1,1,1,1,1},
+    {1,1,1,0,0},
+    {1,1,1,1,1},
+};
+  
+void MyTank::init(Gamepad &pad,N5110 &lcd)
+{
+    this->_x=30;
+    this->_y=43;
+    lcd.drawSprite(_x,_y,5,5,(int *)run_up);
+    this->lcd = lcd;   //Initialize tank direction with LCD
+    this->_pre_d = N;  //Initialize direction of bullet
+    this->count = 0;  //use for the limitting of attack
+    this->attack_gap = 7;//use for the limitting of attack
+    this->HP = 3; 
+    pad.led(1,1); 
+    pad.led(2,1);
+    pad.led(3,1); // the led represent the HP
+    this->totalHP = 3;
+} 
+
+void MyTank::subHP()
+{
+    --HP;
+}
+void MyTank::addHP()
+{
+    ++HP;
+}
+//for the shop :buy the HP
+void MyTank::setHP(Gamepad &pad)
+{
+    pad.tone(500.0,0.1);
+    pad.led(1,1);
+    pad.led(2,1);
+    pad.led(3,1);
+    HP = totalHP;
+    if(HP == 4)
+    pad.led(4,1);
+    if(HP == 5)
+    {
+    pad.led(5,1);
+    pad.led(4,1);
+    }
+    if(HP == 6){    
+    pad.led(6,1);
+    pad.led(5,1);
+    pad.led(4,1);
+    }
+}
+
+int MyTank::MT_HP()
+{
+    return HP;
+}
+
+Vector2D MyTank::get_pos()
+{
+    Vector2D p = {_x,_y};
+    return p;
+}
+
+void MyTank::setpos(int x, int y)
+{
+    this->_x = x;
+    this->_y = y;
+}
+
+void MyTank::read_input(Gamepad &pad){  _d = pad.get_direction();}
+
+// Check the collision between MyTank and Etank
+void MyTank::check_tank_collsion(list<ETank*>&etank)
+{
+    Vector2D mt_pos = get_pos();
+   
+    for(list<ETank*>::iterator it =etank.begin();it!=etank.end();it++)
+    {
+      Vector2D et_pos = (*it)->get_pos();
+      
+        if((mt_pos.x >= et_pos.x && mt_pos.x <= et_pos.x+4) && (mt_pos.y >= et_pos.y && mt_pos.y <=et_pos.y+4)
+        ||(mt_pos.x +4 >= et_pos.x && mt_pos.x <= et_pos.x) && (mt_pos.y >= et_pos.y && mt_pos.y <=et_pos.y+4) 
+        || (mt_pos.x >= et_pos.x && mt_pos.x <= et_pos.x+4) && (mt_pos.y +4>= et_pos.y && mt_pos.y <=et_pos.y)
+        ||(mt_pos.x +4 >= et_pos.x && mt_pos.x <= et_pos.x) &&(mt_pos.y +4>= et_pos.y && mt_pos.y <=et_pos.y)) 
+         {
+        if(_d == S){        
+            _y -= 1; 
+            
+        }  else if(_d == N){   
+            _y += 1;
+              
+        }  else if(_d == E || _d == SE || _d == NE ){
+           _x -= 1; 
+        
+        }  else if(_d == W || _d == SW || _d == NW){        
+           _x += 1; 
+        }
+     }         
+           
+        
+    }  
+} 
+// check the coliison between river and MyTank
+void MyTank::check_pixel()
+{       
+      Vector2D mt_pos = get_pos();
+                                                                                 
+        if((lcd.getPixel(mt_pos.x-1,mt_pos.y)&&(_d == W || _d == SW || _d == NW))   // left
+        ||(lcd.getPixel(mt_pos.x-1,mt_pos.y+4)&&(_d == W || _d == SW || _d == NW))        
+        ||(lcd.getPixel(mt_pos.x+5,mt_pos.y)&&(_d == E || _d == SE || _d == NE))    //right 
+        ||(lcd.getPixel(mt_pos.x+5,mt_pos.y+4)&&(_d == E || _d == SE || _d == NE))   
+        ||(lcd.getPixel(mt_pos.x,mt_pos.y-1)&&_d==N)    // top
+        ||(lcd.getPixel(mt_pos.x+4,mt_pos.y-1)&&_d==N)                                                                               
+        ||(lcd.getPixel(mt_pos.x,mt_pos.y+5)&&_d==S)    //botton   
+        ||(lcd.getPixel(mt_pos.x+4,mt_pos.y+5)&&_d==S))      
+     {
+        if(_d == S){        
+            _y -= 1; 
+            
+            
+        }  else if(_d == N){   
+            _y += 1;
+           
+              
+        }  else if(_d == E || _d == SE || _d == NE ){
+           _x -= 1; 
+           
+        
+        }  else if(_d == W || _d == SW || _d == NW){        
+           _x += 1; 
+           
+        }
+     } 
+    
+}
+
+
+
+// According to the user's direction, select the corresponding pixel tank
+void MyTank::draw(N5110 &lcd)
+{    
+       if(HP == 0)
+      lcd.drawSprite(_x,_y,5,5,(int *)boom);
+      else
+switch(_d)
+ {    
+case S:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_down);
+     _pre_d = S;
+      this->lcd = lcd;
+     break;
+case N:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_up);   
+     _pre_d = N;    
+      this->lcd = lcd;
+     break;
+case W:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_left);  
+     _pre_d = W;
+      this->lcd = lcd;
+     break;   
+case NW:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_left);
+     _pre_d = W;
+      this->lcd = lcd;
+     break;   
+case SW:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_left);
+     _pre_d = W;  
+      this->lcd = lcd;
+     break;           
+case E:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_right);
+     _pre_d = E  ;   
+      this->lcd = lcd;
+     break;
+case SE:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_right); 
+     _pre_d = E;     
+      this->lcd = lcd;
+     break;   
+case NE:
+     lcd.drawSprite(_x,_y,5,5,(int *)run_right);
+     _pre_d = E;   
+      this->lcd = lcd;
+     break; 
+case CENTRE:       
+     lcd = this->lcd;    // keep the same as before
+     break;
+  }     
+}
+
+
+
+
+void MyTank::update(list<ETank*>&etank)
+{   
+      check_pixel();
+     if (_d == S) {      
+        _y+=1;
+
+    } else if (_d == N) { 
+        _y-=1;
+
+    } else if (_d == E || _d == SE || _d == NE) {  
+        _x+=1;
+
+    } else if (_d == W || _d == SW || _d == NW) { 
+        _x-=1;
+
+    }
+    // check the y origin to ensure that the paddle doesn't go off limit
+    if (_y < 6 && _y >=5) {
+        _y = 6;
+    }
+    if (_x < 1 && _x >=0) {
+        _x = 1;
+    }
+    if(_y>43){
+        _y=43;
+    }
+    if(_x>79){
+        _x=79;
+    } 
+    if(_x == -5||_y == -5){
+        _x = -5;
+        _y = -5;
+    }
+   
+   check_tank_collsion(etank);
+}
+
+Direction MyTank::get_direction(){    return _d;   }
+
+//attack of MyTank
+void  MyTank::attack(list<Bullet*>&lstBullets,Vector2D v,Gamepad &pad,N5110 &lcd,list<ETank*>&etank,int &num_tank) 
+{
+    count++;
+    bool check = pad.check_event(Gamepad::A_PRESSED);
+    if(count>attack_gap)
+    if(check== true){
+       v = get_pos();  //get the position of the MyTank 
+       Bullet* bullet = new Bullet(pad,v);// create the bullets when attack
+       lstBullets.push_back(bullet);
+       count = 0;
+    }         
+     for(list<Bullet*>::iterator it = lstBullets.begin(); it != lstBullets.end();)
+     {
+         Vector2D bt_pos = (*it)->get_pos(); 
+        int destroy_check = 0;
+        for(list<ETank*>::iterator eit =etank.begin();eit!=etank.end();){
+           Vector2D et_pos = (*eit)->get_pos();    
+           //Determine whether the enemy is under attack
+           if ((*it)->destroyT(et_pos))    
+           {
+             destroy_check = 1;
+             lcd.drawSprite(et_pos.x,et_pos.y,5,5,(int *)boom);
+             (*eit)->setpos(-5,-5);
+              num_tank--;//ETANK destroyed, quantity -1
+             if((*eit)->lstBullets.empty())   //Avoid etank bullets being removed with etank
+             {
+               delete *eit;
+               eit = etank.erase(eit);
+               continue;
+             }
+           }  
+           eit++;
+        }         
+          if((*it)->destroy()||destroy_check == 1)
+        {
+            delete *it;
+            it = lstBullets.erase(it);
+            continue;
+        } 
+                   
+        (*it)->update(lcd,_pre_d);
+        it++;
+     }    
+     
+}    
+
+
+   
+
+