Hao zhang
/
el17h3z
HaoZhang SID: 201199702
ETank/ETank.cpp
- Committer:
- zh870524589
- Date:
- 2020-05-14
- Revision:
- 2:867fdea920c1
- Parent:
- 1:47fadd485c70
File content as of revision 2:867fdea920c1:
#include "ETank.h" using namespace std; //four directions of ETank 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,0,1,0,1}, }; const int run_down[5][5] = { {1,0,1,0,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,0}, {1,1,1,1,1}, {0,0,1,1,0}, {1,1,1,1,1}, }; const int run_right[5][5] = { {1,1,1,1,1}, {0,1,1,0,0}, {1,1,1,1,1}, {0,1,1,0,0}, {1,1,1,1,1}, }; // create the ETank ETank::ETank(N5110 &lcd,Gamepad &pad) { while(1){ //The position ETanks are allowed to be born in int x = rand()%79; int y = 5+rand()%35; //Make sure ETank avoid overlap if(!(lcd.getPixel(x,y)||lcd.getPixel(x+1,y)||lcd.getPixel(x+2,y)||lcd.getPixel(x+3,y)||lcd.getPixel(x,y+4) ||lcd.getPixel(x+1,y)||lcd.getPixel(x+1,y+1)||lcd.getPixel(x+1,y+2)||lcd.getPixel(x+1,y+3)||lcd.getPixel(x+1,y+4) ||lcd.getPixel(x+2,y)||lcd.getPixel(x+2,y+1)||lcd.getPixel(x+2,y+2)||lcd.getPixel(x+2,y+3)||lcd.getPixel(x+2,y+4) ||lcd.getPixel(x+3,y)||lcd.getPixel(x+3,y+1)||lcd.getPixel(x+3,y+2)||lcd.getPixel(x+3,y+3)||lcd.getPixel(x+3,y+4) ||lcd.getPixel(x+4,y)||lcd.getPixel(x+4,y+1)||lcd.getPixel(x+4,y+2)||lcd.getPixel(x+4,y+3)||lcd.getPixel(x+4,y+4))) { _x = x; _y = y; count = 0;//To limit attack spacing _d = S;//init the direction of ETank pad.tone(100.0,0.1); break; } } } ETank::~ETank() { } void ETank::setpos(int x, int y) { this->_x = x; this->_y = y; } Vector2D ETank::get_pos() { Vector2D p = {_x,_y}; return p; } void ETank::direction(MyTank &mt) { int et_move = rand()%101; // The direction of movement is random Vector2D mt_pos = mt.get_pos();//get position of MyTank //Make sure the ETank is moving in the direction of the target if(_x<mt_pos.x) { if(_y<mt_pos.y && mt_pos.x -_x<60 && mt_pos.y -_y <40) //Make sure the ETank only moves towards MyTank when the target is nearby { if(et_move<62) _d = E; else if(et_move>62) _d = S; } else if(_y>mt_pos.y && mt_pos.x -_x<60 && _y-mt_pos.y <40)//Make sure the ETank only moves towards MyTank when the target is nearby { if(et_move<62) _d = E; else if(et_move>62) _d = N; } else if(_y==mt_pos.y) _d = E; else if(et_move<50) _d = E; // if 1 } else if(_x>mt_pos.x) { if(_y<mt_pos.y && _x -mt_pos.x <60 && mt_pos.y -_y <40)//Make sure the ETank only moves towards MyTank when the target is nearby { if(et_move<62) _d = W; else if(et_move>62) _d = S; } else if(_y>mt_pos.y && _x -mt_pos.x <60 && _y - mt_pos.y <40)//Make sure the ETank only moves towards MyTank when the target is nearby { if(et_move<62) _d = W; else if(et_move>62) _d = N; } else if(_y==mt_pos.y) _d = W; else if(et_move<50) _d = W; } // else if 2 else if(_x==mt_pos.x) { if(_y<mt_pos.y) { _d = S; } else if(_y>mt_pos.y) { _d = N; } } } //draw the ETank in four kinds of ways void ETank::drawE(N5110 &lcd) { switch (_d) { case S: lcd.drawSprite(_x,_y,5,5,(int *)run_down); break; case N: lcd.drawSprite(_x,_y,5,5,(int *)run_up); break; case W: lcd.drawSprite(_x,_y,5,5,(int *)run_left); break; case E: lcd.drawSprite(_x,_y,5,5,(int *)run_right); break; } } bool ETank::collsion_check(Vector2D t1,Vector2D t2) { if(( t1.x>=t2.x && t1.x <= t2.x+4) && (t1.y >= t2.y&& t1.y <=t2.y+4) ||( t1.x+4>=t2.x && t1.x <= t2.x) && (t1.y >= t2.y&& t1.y <=t2.y+4) ||(t1.x>=t2.x && t1.x <= t2.x+4) && (t1.y+4 >= t2.y&& t1.y <=t2.y) ||(t1.x +4>=t2.x && t1.x <= t2.x) && (t1.y+4 >= t2.y&& t1.y <=t2.y)) { return true; } else return false; } //Detect ETank to MyTank collisions void ETank::check_tank_collsion(N5110 &lcd,MyTank &mt) { Vector2D et_pos = get_pos(); Vector2D mt_pos = mt.get_pos(); if(collsion_check(et_pos,mt_pos)) { 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; } } } // Detect collisions among ETanks void ETank::check_self_collsion(list<ETank*>&etank) { Vector2D et_pos = get_pos(); for(list<ETank*>::iterator it =etank.begin();it!=etank.end();it++) { Vector2D eet_pos = (*it)->get_pos(); if(collsion_check(et_pos,eet_pos)&&eet_pos.x !=et_pos.x) // Make sure it's not itself { 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; } } else if(collsion_check(et_pos,eet_pos)&&eet_pos.y !=et_pos.y) // Make sure it's not itself { 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; } } } } void ETank::check_pixel(N5110 &lcd) { Vector2D mt_pos = get_pos(); if((lcd.getPixel(mt_pos.x-1,mt_pos.y)&&_d == W ) // Left of top left corner ||(lcd.getPixel(mt_pos.x-1,mt_pos.y+4)&&_d == W ) // Left of bottom left corner ||(lcd.getPixel(mt_pos.x+5,mt_pos.y)&&_d == E ) // Right of top right corner ||(lcd.getPixel(mt_pos.x+5,mt_pos.y+4)&&_d == E ) //Right of bottom right corner ||(lcd.getPixel(mt_pos.x,mt_pos.y-1)&&_d==N) // Top of Top left corner ||(lcd.getPixel(mt_pos.x+4,mt_pos.y-1)&&_d==N) //Top of Top right corner ||(lcd.getPixel(mt_pos.x,mt_pos.y+5)&&_d==S) //Bottom of left corner ||(lcd.getPixel(mt_pos.x+4,mt_pos.y+5)&&_d==S)) //Bottom of right corner { 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; } } } void ETank::update(N5110 &lcd,MyTank &mt,list<ETank*>&etank) { check_pixel(lcd); check_tank_collsion(lcd,mt); Vector2D mt_pos = mt.get_pos(); if(_x!= mt_pos.x && _y!= mt_pos.y) { if (_d == S) { this-> _y+=1; } else if (_d == N) { this-> _y-=1; } else if (_d == E || _d == SE || _d == NE) { this-> _x+=1; } else if (_d == W || _d == SW || _d == NW) { this-> _x-=1; } // ensure the ETank will not move out of the scope if (_y < 6 && _y >=5) { this-> _y = 6; } if (_x < 1 && _x >=0) { this-> _x = 1; } if(_y>43){ this-> _y=43; } if(_x>79){ this-> _x=79; } //step of destroy the ETank if(_x == -5||_y == -5){ this-> _x = -5; this-> _y = -5; } } check_self_collsion(etank); } void ETank::attack(Vector2D v,Gamepad &pad,N5110 &lcd,MyTank &mt,list<Bullet*> &mtbullet,int et_attack,int timegap) { count++; if(count>timegap) // Time interval between attacks if(et_attack>40){//possibility of attack v = get_pos(); // get the position of the ETank Bullet* bullet = new Bullet(pad,v); // create the bullets when attack lstBullets.push_back(bullet); count = 0; } Vector2D mt_pos = mt.get_pos(); for(list<Bullet*>::iterator it = lstBullets.begin(); it != lstBullets.end();) { if((*it)->destroy()) { delete *it; it = lstBullets.erase(it); // delete the bullet continue; } else if ((*it)->destroyT(mt_pos)) { delete *it; it = lstBullets.erase(it); mt.subHP(); int M_HP = mt.MT_HP(); // MyTank's health is reduced when the bullet hits the target pad.tone(500.0,0.1); if(M_HP == 5) pad.led(6,0); if(M_HP == 4) pad.led(5,0); if(M_HP == 3) pad.led(4,0); if(M_HP==2) pad.led(3,0); if(M_HP==1) pad.led(2,0); if(M_HP==0){ pad.led(1,0); mt.draw(lcd); } continue; } (*it)->et_update(lcd,_d);//update the bullet (*it)->bullet_collison(lstBullets,mtbullet); //check the collsion between bulltes it++; } }