Ikenna Adrian Ozoemena 201157039
Dependencies: mbed
Enemy/Enemy.cpp
- Committer:
- ikenna1
- Date:
- 2019-05-09
- Revision:
- 53:3fdc4486f672
- Parent:
- 51:2231e2e141b9
File content as of revision 53:3fdc4486f672:
#include "Enemy.h" Enemy::Enemy() { } Enemy::~Enemy() { } // enemy sprites const int seeker[7][9] = { {1,1,0,0,0,0,0,1,1}, {1,0,1,0,0,0,1,0,1}, {1,0,0,1,1,1,0,0,1}, {0,1,0,0,0,0,0,1,0}, {0,0,1,0,0,0,1,0,0}, {0,0,1,1,0,1,1,0,0}, {0,0,0,0,1,0,0,0,0}, }; const int shooter[10][11] = { {0,0,1,0,0,0,0,0,1,0,0}, {0,1,0,1,0,0,0,1,0,1,0}, {1,0,0,1,0,1,0,1,0,0,1}, {1,0,0,1,1,0,1,1,0,0,1}, {0,1,0,0,0,0,0,0,0,1,0}, {0,1,0,0,1,1,1,0,0,1,0}, {0,0,1,0,0,1,0,0,1,0,0}, {0,0,0,1,0,0,0,1,0,0,0}, {0,0,0,0,1,0,1,0,0,0,0}, {0,0,0,0,0,1,0,0,0,0,0}, }; void Enemy::init(int noShooters, int noSeekers) { // initialize the number of seekers and shooters _noSeekers = noSeekers; _noShooters = noShooters; // initialize seeker at top of screen whith a random x position _seekerPos[0].x = rand_no(68); _seekerPos[0].y = 0; _seekerPos[1].x = rand_no(68); _seekerPos[1].y = 0; _seekerPos[2].x = rand_no(68); _seekerPos[2].y = 0; // initialize shooter at top of screen whith a random x position _shooterPos[0].x = rand_no(68); _shooterPos[0].y = 1; _shooterPos[1].x = rand_no(68); _shooterPos[1].y = 1; _shooterPos[2].x = rand_no(68); _shooterPos[2].y = 1; // initialize shooter speed _shooterSpeed[0].x = 1; _shooterSpeed[1].x = 1; _shooterSpeed[2].x = 1; _shooterSpeed[0].y = 1; _shooterSpeed[1].y = 1; _shooterSpeed[2].y = 1; } void Enemy::set_noshooters(int noShooters) { // set the number of enemy shooters _noShooters = noShooters; } void Enemy::set_noseekers(int noSeekers) { // set the number of enemy seekers _noSeekers = noSeekers; } void Enemy::draw_seeker(N5110 &lcd) { // Draw seekers based on _noSeekers with a maximum of three seekers switch (_noSeekers) { case 1: lcd.drawSprite( _seekerPos[0].x, _seekerPos[0].y,7,9,(int *)seeker); break; case 2: lcd.drawSprite( _seekerPos[0].x, _seekerPos[0].y,7,9,(int *)seeker); lcd.drawSprite( _seekerPos[1].x, _seekerPos[1].y,7,9,(int *)seeker); break; case 3: lcd.drawSprite( _seekerPos[0].x, _seekerPos[0].y,7,9,(int *)seeker); lcd.drawSprite( _seekerPos[1].x, _seekerPos[1].y,7,9,(int *)seeker); lcd.drawSprite( _seekerPos[2].x, _seekerPos[2].y,7,9,(int *)seeker); break; } } void Enemy::draw_shooter(N5110 &lcd) { // Draw shooters based on _noShooters with a maximum of three shooters switch (_noShooters) { case 1: lcd.drawSprite(_shooterPos[0].x,_shooterPos[0].y,10,11,(int *)shooter); break; case 2: lcd.drawSprite(_shooterPos[0].x,_shooterPos[0].y,10,11,(int *)shooter); lcd.drawSprite(_shooterPos[1].x,_shooterPos[1].y,10,11,(int *)shooter); break; case 3: lcd.drawSprite(_shooterPos[0].x,_shooterPos[0].y,10,11,(int *)shooter); lcd.drawSprite(_shooterPos[1].x,_shooterPos[1].y,10,11,(int *)shooter); lcd.drawSprite(_shooterPos[2].x,_shooterPos[2].y,10,11,(int *)shooter); break; } } void Enemy::update_seeker(int ship_xpos, int ship_ypos) { // Update seekers based on _noSeekers with a maximum of three seekers switch (_noSeekers) { case 1: _seekerPos[0] = seeker_motion(_seekerPos[0].x,_seekerPos[0].y,ship_xpos,ship_ypos,2,2); break; case 2: _seekerPos[0] = seeker_motion(_seekerPos[0].x,_seekerPos[0].y,ship_xpos,ship_ypos,2,2); _seekerPos[1] = seeker_motion(_seekerPos[1].x,_seekerPos[1].y,ship_xpos,ship_ypos,2,2); break; case 3: _seekerPos[0] = seeker_motion(_seekerPos[0].x,_seekerPos[0].y,ship_xpos,ship_ypos,2,2); _seekerPos[1] = seeker_motion(_seekerPos[1].x,_seekerPos[1].y,ship_xpos,ship_ypos,2,2); _seekerPos[2] = seeker_motion(_seekerPos[2].x,_seekerPos[2].y,ship_xpos,ship_ypos,2,2); break; } } void Enemy::update_shooter(int ship_xpos, int ship_ypos) { // Update shooters based on _noShooters with a maximum of three shooters switch (_noShooters) { case 1: _shooterPos[0] = shooter_motion(_shooterPos[0].x,_shooterPos[0].y,ship_xpos,ship_ypos,_shooterWPos[0].x,_shooterWPos[0].y,_shooterSpeed[0].x,_shooterSpeed[0].y); break; case 2: _shooterPos[0] = shooter_motion(_shooterPos[0].x,_shooterPos[0].y,ship_xpos,ship_ypos,_shooterWPos[0].x,_shooterWPos[0].y,_shooterSpeed[0].x,_shooterSpeed[0].y); _shooterPos[1] = shooter_motion(_shooterPos[1].x,_shooterPos[1].y,ship_xpos,ship_ypos,_shooterWPos[1].x,_shooterWPos[1].y,_shooterSpeed[1].x,_shooterSpeed[1].y); break; case 3: _shooterPos[0] = shooter_motion(_shooterPos[0].x,_shooterPos[0].y,ship_xpos,ship_ypos,_shooterWPos[0].x,_shooterWPos[0].y,_shooterSpeed[0].x,_shooterSpeed[0].y); _shooterPos[1] = shooter_motion(_shooterPos[1].x,_shooterPos[1].y,ship_xpos,ship_ypos,_shooterWPos[1].x,_shooterWPos[1].y,_shooterSpeed[1].x,_shooterSpeed[1].y); _shooterPos[2] = shooter_motion(_shooterPos[2].x,_shooterPos[2].y,ship_xpos,ship_ypos,_shooterWPos[2].x,_shooterWPos[2].y,_shooterSpeed[2].x,_shooterSpeed[2].y); break; } } Vector2D Enemy::seeker_motion(int seeker_xpos,int seeker_ypos,int ship_xpos,int ship_ypos,int vx,int vy) { int rangex = seeker_xpos - ship_xpos; int rangey = seeker_ypos - ship_ypos; // make seeker move towards ship if(rangey < 0) { if(rangex < 0) { seeker_xpos = seeker_xpos + vx; } else if(rangex == 0) { seeker_xpos = seeker_xpos + vx; } else { seeker_xpos = seeker_xpos - vx; } } // reset seeker to top once it has left the screen if( seeker_ypos > 54) { seeker_xpos = rand_no(68); seeker_ypos = 0; } seeker_ypos = seeker_ypos + vy; return{seeker_xpos,seeker_ypos}; } Vector2D Enemy::shooter_motion(int shooter_xpos,int shooter_ypos,int ship_xpos, int ship_ypos, int projx, int projy,int vx, int vy) { // The shooter tracks the ship based on where the bullet it has fired is int high_bar =10; int low_bar = 25; int rangex = shooter_xpos - ship_xpos; int rangey = shooter_ypos - ship_ypos; // is the bullet has left the shooter and is around the middle of the screen it will avoid the ship if(high_bar <= projy && projy <= low_bar) { if(rangex > 0) { // avoid ship shooter_xpos = shooter_xpos + vx; } if(rangex < 0) { shooter_xpos = shooter_xpos - vx; } } else { // if it has past a certain point the shooter will try to line up the next shot // track ship if(rangex > 0) { shooter_xpos = shooter_xpos - vx; } if(rangex < 0) { shooter_xpos = shooter_xpos + vx; } } // dont let the shooter leave the screen if(shooter_xpos < 1) { shooter_xpos = 1; } if(shooter_xpos > 84 - 8 - 11) { shooter_xpos = 84 - 8 - 11; } return{shooter_xpos,shooter_ypos}; } void Enemy::draw_shw1(N5110 &lcd,Gamepad &pad) { _shooterWSpeed[0].x = 0; //Projectile doesn't move sideways. _shooterWSpeed[0].y = 2; //Projectile donwards //resets once projectile reaches bottom of screen if(_shooterWPos[0].y >= 48) { _reset[0] = 0; } if(_reset[0] == 0) { _shooterWPos[0].x = _shooterPos[0].x + 5; _shooterWPos[0].y = _shooterPos[0].y + 11; _reset[0] = _reset[0] + 1; } lcd.drawRect(_shooterWPos[0].x,_shooterWPos[0].y,1,1,FILL_BLACK); // printf("Ship x and y pos, reset = %d , %d ,%d \n", _ship_xpos, _ship_ypos, reset); } void Enemy::draw_shw2(N5110 &lcd,Gamepad &pad) { _shooterWSpeed[1].x = 0; //Projectile doesn't move sideways. _shooterWSpeed[1].y = 5; //Projectile moves downwards //resets once projectile reaches bottom of screen if(_shooterWPos[1].y >= 48) { _reset[1]= 0; } if(_reset[1] == 0) { _shooterWPos[1].x = _shooterPos[1].x + 5; _shooterWPos[1].y = _shooterPos[1].y + 11; _reset[1] = _reset[1] + 1; } lcd.drawRect(_shooterWPos[1].x,_shooterWPos[1].y,1,1,FILL_BLACK); // printf("Ship x and y pos, reset = %d , %d ,%d \n", _ship_xpos, _ship_ypos, reset); } void Enemy::draw_shw3(N5110 &lcd,Gamepad &pad) { _shooterWSpeed[2].x = 0; //Projectile doesn't move sideways. _shooterWSpeed[2].y = 3; //Projectile moves upwards on screen. //resets once projectile reaches bottom of screen if(_shooterWPos[2].y >= 48) { _reset[2] = 0; } if(_reset[2] == 0) { _shooterWPos[2].x = _shooterPos[2].x + 5; _shooterWPos[2].y = _shooterPos[2].y + 11; _reset[2] = _reset[2] + 1; } lcd.drawRect(_shooterWPos[2].x,_shooterWPos[2].y,1,1,FILL_BLACK); } void Enemy::draw_shw(N5110 &lcd,Gamepad &pad) { // Draw projectiles depending on the number of shooters switch (_noShooters) { case 1: draw_shw1(lcd,pad); break; case 2: draw_shw1(lcd,pad); draw_shw2(lcd,pad); break; case 3: draw_shw1(lcd,pad); draw_shw2(lcd,pad); draw_shw3(lcd,pad); break; } } void Enemy::update_shw() { // update the shooters position based on the shooter projectile speed _shooterWPos[0].x = _shooterWPos[0].x + _shooterWSpeed[0].x; _shooterWPos[0].y = _shooterWPos[0].y + _shooterWSpeed[0].y; _shooterWPos[1].x = _shooterWPos[1].x + _shooterWSpeed[1].x; _shooterWPos[1].y = _shooterWPos[1].y + _shooterWSpeed[1].y; _shooterWPos[2].x = _shooterWPos[2].x + _shooterWSpeed[2].x; _shooterWPos[2].y = _shooterWPos[2].y + _shooterWSpeed[2].y; } Vector2D Enemy::get_shwpos(int shno) { // get appropriate shooter projectile position if(shno == 1) { Vector2D pos = {_shooterWPos[0].x,_shooterWPos[0].y}; return pos; } if(shno == 2) { Vector2D pos = {_shooterWPos[1].x,_shooterWPos[1].y}; return pos; } if(shno == 3) { Vector2D pos = {_shooterWPos[2].x,_shooterWPos[2].y}; return pos; } } void Enemy::reset_seeker(int seno) { // reset seeker to top of screen switch (seno) { case 1: _seekerPos[0].x = rand_no(68); _seekerPos[0].y = 0; break; case 2: _seekerPos[1].x = rand_no(68); _seekerPos[1].y = 0; break; case 3: _seekerPos[2].x = rand_no(68); _seekerPos[2].y = 0; break; } } void Enemy::reset_shooter(int shno) { // reset shooter to top of screen switch (shno) { case 1: _shooterPos[0].x = rand_no(68); _shooterPos[0].y = 5; break; case 2: _shooterPos[1].x = rand_no(68); _shooterPos[1].y = 5; break; case 3: _shooterPos[2].x = rand_no(68); _shooterPos[2].y = 5; break; } } Vector2D Enemy::get_seekerpos(int seno) { // get appropriate seeker position if(seno == 1) { Vector2D seeker_pos = { _seekerPos[0].x, _seekerPos[0].y}; return seeker_pos; } if(seno == 2) { Vector2D seeker_pos = { _seekerPos[1].x, _seekerPos[1].y}; return seeker_pos; } if(seno == 3) { Vector2D seeker_pos = { _seekerPos[2].x, _seekerPos[2].y}; return seeker_pos; } } Vector2D Enemy::get_shooterpos(int shno) { // get appropriate shooter position if(shno == 1) { Vector2D shooter_pos = {_shooterPos[0].x,_shooterPos[0].y}; return shooter_pos; } if(shno == 2) { Vector2D shooter_pos = {_shooterPos[1].x,_shooterPos[1].y}; return shooter_pos; } if(shno == 3) { Vector2D shooter_pos = {_shooterPos[2].x,_shooterPos[2].y}; return shooter_pos; } } int Enemy::rand_no(int scale) { // seed the srand function using time from the <ctime> library srand(time(NULL)); int rand_no = (rand() %scale) + 1; // use scale to limit the output of the random number // printf("random no = %d\n",rand_no); return rand_no; } void Enemy::sh_scaling(float time_elapsed) { int vmax = 3; int time = floor(time_elapsed); // Increase the shooters speed every 20 seconds to a maximum of 3 if(time%20 == 0) { if(_shooterSpeed[0].x > -vmax && _shooterSpeed[0].x < vmax) { _shooterSpeed[0].x = _shooterSpeed[0].x * 1.1; } if(_shooterSpeed[1].x > - vmax && _shooterSpeed[1].x < vmax) { _shooterSpeed[1].x = _shooterSpeed[1].x * 1.1; } if(_shooterSpeed[2].x > -vmax && _shooterSpeed[2].x < vmax) { _shooterSpeed[2].x = _shooterSpeed[2].x * 1.1; } if(_shooterSpeed[0].y > -vmax && _shooterSpeed[0].y < vmax) { _shooterSpeed[0].y = _shooterSpeed[0].y * 1.1; } if(_shooterSpeed[1].y > -vmax && _shooterSpeed[1].y < vmax) { _shooterSpeed[1].y = _shooterSpeed[1].y * 1.1; } if(_shooterSpeed[2].y > -vmax && _shooterSpeed[2].y < vmax) { _shooterSpeed[2].y = _shooterSpeed[2].y * 1.1; } } // printf("time = %d, _shooterSpeed[0].x = %f\n",time,_shooterSpeed[0].x); } int Enemy::distance(int x1, int y1, int x2, int y2) { // get the absolute difference between x1 and x2, and y1 and y2 // then average that int rangex = abs(x1 - x2); int rangey = abs(y1 - y2); int dis = (rangex+rangey)/2; return dis; } Vector2D Enemy::find_closest(int ship_xpos,int ship_ypos, int noSeekers, int noShooters) { // get the distance for all enemies int sh1 = distance(ship_xpos,ship_ypos,_shooterPos[0].x,_shooterPos[0].y); int sh2 = distance(ship_xpos,ship_ypos,_shooterPos[1].x,_shooterPos[1].y); int sh3 = distance(ship_xpos,ship_ypos,_shooterPos[2].x,_shooterPos[2].y); int se1 = distance(ship_xpos,ship_ypos, _seekerPos[0].x, _seekerPos[0].y); int se2 = distance(ship_xpos,ship_ypos, _seekerPos[1].x, _seekerPos[1].y); int se3 = distance(ship_xpos,ship_ypos, _seekerPos[2].x, _seekerPos[2].y); int close[6] = {sh1,sh2,sh3,se1,se2,se3}; // find index of the smallest element int index; int smallest = close[0]; for(int i=0; i<6; i=i+1) { if(smallest>close[i]) { smallest=close[i]; index = i; } } // return the position of the closest enemy if(index == 0 && noShooters >= 1) { return {_shooterPos[0].x,_shooterPos[0].y}; } if(index == 1 && noShooters >= 2) { return {_shooterPos[1].x,_shooterPos[1].y}; } if(index == 2 && noShooters >= 3) { return {_shooterPos[2].x,_shooterPos[2].y}; } if(index == 3 && noSeekers >= 1 ) { return { _seekerPos[0].x, _seekerPos[0].y}; } if(index == 4 && noSeekers >= 2) { return { _seekerPos[1].x, _seekerPos[1].y}; } if(index == 5 && noSeekers >= 3) { return { _seekerPos[2].x, _seekerPos[2].y}; } }