HaoZhang SID: 201199702

Dependencies:   mbed

MyTank/MyTank.cpp

Committer:
zh870524589
Date:
2020-05-14
Revision:
2:867fdea920c1
Parent:
1:47fadd485c70

File content as of revision 2:867fdea920c1:

#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++;
     }    
     
}