Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
RosenEngine/RosenEngine.cpp
- Committer:
- ikenna1
- Date:
- 2019-05-09
- Revision:
- 52:29772e31a620
- Parent:
- 49:aa204bf7ee2e
- Child:
- 53:3fdc4486f672
File content as of revision 52:29772e31a620:
#include "RosenEngine.h" DigitalIn A(PTB9); // Constructor RosenEngine::RosenEngine() { } // Destructor RosenEngine::~RosenEngine() { } void RosenEngine::init(int ship_width,int ship_height,int ship_speed,int ship_xpos,int ship_ypos) { // initialise the game parameters _ship.init(ship_width,ship_height,ship_speed,ship_xpos,ship_ypos); _no_shooters = 0; _no_seekers = 0; _enemy.init(_no_shooters,_no_seekers); _menu.init(16); _health.init(_shipUsed); _times_run = 0; _score = 0; _dead = false; _intro = false; _wait_time = 2.25; } void RosenEngine::reset() { // reinitialize parameters once back is pressed and game is exited _enemy.init(_no_shooters,_no_seekers); _health.init(_shipUsed); _wait_time = 2.25; _times_run = 0; _score = 0; _no_shooters = 0; _dead = false; _no_seekers = 0; } void RosenEngine::read_input(Gamepad &pad) { // read all inputs from the gamepad Vector2D mapped_coord = pad.get_coord(); _joystick.x = mapped_coord.x; _joystick.y = mapped_coord.y; _d = pad.get_direction(); wait(0.1); // printf("_joystick.x ,_joystick.y = %f , %f\n",_joystick.x, _joystick.y); } void RosenEngine::draw(N5110 &lcd, Gamepad &pad) { // Draw border lcd.drawRect(0,0,78,48,FILL_TRANSPARENT); // Draw all other game assets _health.draw_health(lcd,_shipUsed); _health.draw_shields(lcd); _enemy.draw_seeker(lcd); _enemy.draw_shooter(lcd); _enemy.draw_shw(lcd,pad); draw_ship(lcd,pad); disp_points(lcd); // if player dies display death scene if(_dead == true) { game_over(lcd); } } void RosenEngine::draw_ship(N5110 &lcd, Gamepad &pad) { // find the closest enemy (used in orions firing) Vector2D inde = find_closest1(); int index = inde.x; Vector2D closest = find_closest2(index); // Draw ships and set ship parameters depending on the ship being used switch (_shipUsed) { case kestrel: _ship.set_parameters(9,6,4); _ship.draw_ship(lcd,_shipUsed); _weapons.draw(lcd,pad,_shipUsed,closest); break; case imperion: _ship.set_parameters(7,10,2); _ship.draw_ship(lcd,_shipUsed); _weapons.draw(lcd,pad,_shipUsed,closest); break; case orion: _ship.set_parameters(7,10,3); _ship.draw_ship(lcd,_shipUsed); _weapons.draw(lcd,pad,_shipUsed,closest); break; } //printf("_shipUsed = %d\n",_shipUsed); } void RosenEngine::update(Gamepad &pad) { // set the ship in use (kestrel imperion or orion) set_shipUsed(); // update enemies _enemy.update_seeker(_shipPos.x, _shipPos.y); _enemy.update_shooter(_shipPos.x, _shipPos.y); _enemy.update_shw(); // update ship weapons update_ship_weapon(pad); // check collisions shooter_ship_collision(pad); seeker_ship_collision(pad); shooterw_ship_collision(pad); imperionw_seeker_collision(pad); kestrelw_shooter_collision(pad); imperionw_shooter_collision(pad); orionw_collision(pad); // check health check_health(); // increase difficulty over time scaling(timer(12)); } void RosenEngine::update_ship_weapon(Gamepad &pad) { // update ship weapons based on ship being used if(_shipUsed == kestrel) { _ship.update_ship(_joystick.x,_joystick.y); _weapons.update(); kestrelw_seeker_collision(pad); } if(_shipUsed == imperion && A == false) { _ship.update_ship(_joystick.x,_joystick.y); _weapons.update(); } if(_shipUsed == orion) { _ship.update_ship(_joystick.x,_joystick.y); _weapons.update(); } } void RosenEngine::get_pos() { // get ship position _shipPos = _ship.get_pos(); // get enemy position _seekerPos[0] = _enemy.get_seekerpos(1); _seekerPos[1] = _enemy.get_seekerpos(2); _seekerPos[2] = _enemy.get_seekerpos(3); _shooterPos[0] = _enemy.get_shooterpos(1); _shooterPos[1] = _enemy.get_shooterpos(2); _shooterPos[2] = _enemy.get_shooterpos(3); _shooterWPos[0] = _enemy.get_shwpos(1); _shooterWPos[1] = _enemy.get_shwpos(2); _shooterWPos[2] = _enemy.get_shwpos(3); // set ship size set_ship_size(); // weapons are initialized here to pass accurate size values to the weapon class _weapons.init(_shipPos.x, _shipPos.y, _shipWidth); _ycursor = _menu.get_ycursor(); } void RosenEngine::set_ship_size() { // change ship size depending on ship being used switch (_shipUsed) { case kestrel: _shipWidth = 9; _shipHeight = 6; break; case imperion: _shipWidth = 7; _shipHeight = 10; break; case orion: _shipWidth = 7; _shipHeight = 10; break; } } void RosenEngine::title(N5110 &lcd) { // display main menu screen _menu.title(lcd,_shipUsed); _menu.update(_d,_joystick); } int RosenEngine::get_ycursor() { _ycursor = _menu.get_ycursor(); return _ycursor; } void RosenEngine::set_shipUsed() { // assign the ship being used based on xcursor which is the cursor in // the ship select part of the menu int shipno = _menu.get_xcursor(); _shipUsed = (SHIP)shipno; } void RosenEngine::ship_select(N5110 &lcd) { _menu.update(_d,_joystick); _menu.disp_ships(lcd); } bool RosenEngine::check_collision(int xpos1, int ypos1,int width1,int height1,int xpos2, int ypos2,int width2,int height2) { // Create arrays of all positions with appropriate height and length int xpos1_array[width1]; int ypos1_array[height1]; int xpos2_array[width2]; int ypos2_array[height2]; bool xcol = false; bool ycol = false; bool col = false; //printf("variables declared\n"); // Loop through both height and width to get a 2D aray of the sprites position // and compare all positionr returning true is any match for(int cx = 0; cx<width1; cx=cx+1) { xpos1_array[cx]= xpos1 + cx; for(int nx = 0; nx<width2; nx=nx+1) { xpos2_array[nx]= xpos2 + nx; if(xpos2_array[nx] == xpos1_array[cx]) { xcol = true; } } } //printf("first loop done\n"); for(int cy = 0; cy<height1; cy=cy+1) { ypos1_array[cy]= ypos1 + cy; for(int ny = 0; ny<height2; ny=ny+1) { ypos2_array[ny]= ypos2 + ny; if(ypos2_array[ny] == ypos1_array[cy]) { ycol = true; } } } // if both the hight and width position values are equal a collision has occured col = (xcol & ycol); return col; } bool RosenEngine::check_collision1(int xpos1,int width1,int xpos2,int width2) { // Create arrays of all positions with appropriate width values int xpos1_array[width1]; int xpos2_array[width2]; bool xcol = false; // loop through both arrays comparing their values and return true if any are equal for(int cx = 0; cx<width1; cx=cx+1) { xpos1_array[cx]= xpos1 + cx; for(int nx = 0; nx<width2; nx=nx+1) { xpos2_array[nx]= xpos2 + nx; if(xpos2_array[nx] == xpos1_array[cx]) { xcol = true; } } } return xcol; } void RosenEngine::seeker_ship_collision(Gamepad &pad) { bool col1,col2,col3; // Check for any collisions using the check_collision function col1 = check_collision(_shipPos.x,_shipPos.y,9,6,_seekerPos[0].x, _seekerPos[0].y,10,7); col2 = check_collision(_shipPos.x,_shipPos.y,9,6,_seekerPos[1].x, _seekerPos[1].y,10,7); col3 = check_collision(_shipPos.x,_shipPos.y,9,6,_seekerPos[2].x, _seekerPos[2].y,10,7); int sel = 0; if (col1 == true && _no_seekers >= 1) { sel = 1; } if (col2 == true && _no_seekers >= 2) { sel = 2; } if (col3 == true && _no_seekers >= 3) { sel = 3; } // printf("col1 = %d, col2 = %d, col3 = %d, no_seekers = %d\n",col1,col2,col3,_no_seekers); // if there is a collision between any seeker and the ship update both the seeker and the ships health if(sel != 0) { _health.update(5,pad); _health.seekerh_update(sel,10); pad.tone(500,0.05); wait(0.05); } } void RosenEngine::shooter_ship_collision(Gamepad &pad) { bool col1,col2,col3; int sel = 0; // Check for any collisions using the check_collision function col1 = check_collision(_shipPos.x,_shipPos.y,9,6,_shooterPos[0].x, _shooterPos[1].y,10,7); col2 = check_collision(_shipPos.x,_shipPos.y,9,6,_shooterPos[1].x, _shooterPos[0].y,10,7); col3 = check_collision(_shipPos.x,_shipPos.y,9,6,_shooterPos[2].x, _shooterPos[0].y,10,7); if(col1 == true && _no_shooters >= 1) { sel = 1; } if(col2 == true && _no_shooters >= 2) { sel = 2; } if(col3 == true && _no_shooters >= 3) { sel = 3; } // if there is a collision between any shooter and the ship update both the shooter and the ships health if(sel != 0) {// sel is default 0 and will only change if a collision occurs _health.update(1,pad); _health.shooterh_update(sel,10); pad.tone(500,0.05); wait(0.05); } } void RosenEngine::shooterw_ship_collision(Gamepad &pad) { bool col1,col2,col3; int sel = 0; // Check for any collisions using the check_collision function col1 = check_collision(_shipPos.x,_shipPos.y,9,6,_shooterWPos[0].x, _shooterWPos[1].y,2,2); col2 = check_collision(_shipPos.x,_shipPos.y,9,6,_shooterWPos[1].x, _shooterWPos[2].y,2,2); col3 = check_collision(_shipPos.x,_shipPos.y,9,6,_shooterWPos[2].x, _shooterWPos[2].y,2,2); if(col1 == true && _no_shooters >= 1) { sel = 1; } if(col2 == true && _no_shooters >= 2) { sel = 2; } if(col3 == true && _no_shooters >= 3) { sel = 3; } // if there is a collision and the ship was hit update the ships damage if(sel != 0) {// sel is default 0 and will only change if a collision occurs _health.update(1,pad); pad.tone(500,0.05); wait(0.05); } } void RosenEngine::kestrelw_seeker_collision(Gamepad &pad) { // the kestrel fires a projectile whose x and y values must be checked with the // x, and y, values of every enemy to check for a collision bool col1, col2, col3; int sel = 0; Vector2D missle_pos = _weapons.get_pos(_shipUsed); // get the kestrel's projectile position // Check for any collisions using the check_collision function col1 = check_collision(_seekerPos[0].x,_seekerPos[0].y,9,6,missle_pos.x,missle_pos.y,1,1); col2 = check_collision(_seekerPos[1].x,_seekerPos[1].y,9,6,missle_pos.x,missle_pos.y,1,1); col3 = check_collision(_seekerPos[2].x,_seekerPos[2].y,9,6,missle_pos.x,missle_pos.y,1,1); if (col1 == true && _no_seekers >= 1) { sel = 1; } if (col2 == true && _no_seekers >= 2) { sel = 2; } if (col3 == true && _no_seekers >= 3) { sel = 3; } // if there are collisions update the seekers health if(sel != 0) {// sel is default 0 and will only change if a collision occurs pad.tone(500,0.05); _health.seekerh_update(sel,5); wait(0.05); } } void RosenEngine::imperionw_seeker_collision(Gamepad &pad) { // the imperion fires a lazer to the top of screen as such we don't need to check all the // x, y values for the sprite to be sure of collisions just the x value. as long as the ship is above // the targetted enemy a collision will register bool col1,col2,col3; int sel = 0; if(_shipUsed == imperion) { if(_shipPos.y > _seekerPos[0].y + 6) { // only regiser if seeker is above ship col1 = check_collision1(_seekerPos[0].x,9,_shipPos.x + 2,3); // check for collision using the check_collision1 function if (col1 == true && A == true && _no_seekers >= 1) { sel = 1; // if there is a collision set an appropriate select value } } if(_shipPos.y > _seekerPos[1].y + 6) { col2 = check_collision1(_seekerPos[1].x,9,_shipPos.x + 2,3); if (col2 == true && A == true && _no_seekers >= 2) { sel = 2; } } if(_shipPos.y > _seekerPos[0].y + 6) { col3 = check_collision1(_seekerPos[2].x,9,_shipPos.x + 2,3); if (col3 == true && A == true && _no_seekers >= 3) { sel = 3; } } } // if a collision occured update the seekers health if(sel != 0) {// sel is default 0 and will only change if a collision occurs _health.seekerh_update(sel,10); pad.tone(500,0.05); wait(0.05); } } void RosenEngine::kestrelw_shooter_collision(Gamepad &pad) { Vector2D missle_pos = _weapons.get_pos(_shipUsed); // get the kestrel's projectile position bool col1, col2, col3; int sel = 0; // Check for any collisions using the check_collision function col1 = check_collision(_shooterPos[0].x,_shooterPos[0].y,9,6,missle_pos.x,missle_pos.y,1,1); col2 = check_collision(_shooterPos[1].x,_shooterPos[1].y,9,6,missle_pos.x,missle_pos.y,1,1); col3 = check_collision(_shooterPos[2].x,_shooterPos[2].y,9,6,missle_pos.x,missle_pos.y,1,1); if (col1 == true && _no_shooters >= 1) { sel = 1; } if (col2 == true && _no_shooters >= 2) { sel = 2; } if (col3 == true && _no_shooters >= 3) { sel = 3; } // if a collision did occur update the right shooter using the select value if(sel != 0) { // sel is default 0 and will only change if a collision occurs pad.tone(500,0.05); _health.shooterh_update(sel,5); wait(0.05); } } void RosenEngine::imperionw_shooter_collision(Gamepad &pad) { bool col1,col2,col3; int sel = 0; // check collision using check_collision1 function if(_shipUsed == imperion) { if(_shipPos.y > _shooterPos[0].y + 6) { col1 = check_collision1(_shooterPos[0].x,9,_shipPos.x + 2,3); if (col1 == true && A == true && _no_shooters >= 1) { sel = 1; } } if(_shipPos.y > _shooterPos[1].y + 6) { col2 = check_collision1(_shooterPos[1].x,9,_shipPos.x + 2,3); if (col2 == true && A == true && _no_shooters >= 2) { sel = 2; } } if(_shipPos.y > _shooterPos[2].y + 6) { col3 = check_collision1(_shooterPos[2].x,9,_shipPos.x + 2,3); if (col3 == true && A == true && _no_shooters >= 3) { sel = 3; } } } // if a collision did occur update the shooters health if(sel != 0) {// sel is default 0 and will only change if a collision occurs _health.shooterh_update(sel,10); pad.tone(500,0.05); wait(0.05); } } void RosenEngine::orionw_collision(Gamepad &pad) { // the orions weapon is an arc weapon that latches on to the nearest enemy. // as the nearest enemy position has already been found in dind_closest() // all we need to do now is ensure that the enemy is within range of the orions weapon Vector2D inde = find_closest1(); int index1 = inde.x; int index2 = inde.x - 3; int distance = inde.y; // enemy 1,2 and 3 are shooters if(_no_shooters >= index1 && A == true && distance < 15) {// the wepon fires when a is pressed and the enemy ship is within the distaance _health.shooterh_update(index1,10); pad.tone(500,0.05); wait(0.05); } // enemy 4,5 and 6 are seekers so 3 is subtracted from inde.x to compensate if(_no_seekers >= index2 && A == true && distance < 15) { _health.seekerh_update(index2,10); pad.tone(500,0.05); wait(0.05); } } void RosenEngine::check_health() { // check player and enemy health check_se_health(); check_sh_health(); Vector2D hp = _health.get_hp(); if(hp.x <= 0) { // printf("player deaad\n"); _dead = true; } } void RosenEngine::check_se_health() { // set sel (select) as default 0 int sel = 0; // get the seekers health int seeker1_health = _health.get_seekerh(1); int seeker2_health = _health.get_seekerh(2); int seeker3_health = _health.get_seekerh(3); // printf("seeker1_h = %d, seeker2_h = %d, seeker3_h = %d\n",seeker1_health,seeker2_health,seeker3_health); // set sel (select) depending on if any seekers health falls below zero if(seeker1_health == 0) { sel = 1; } if(seeker2_health == 0) { sel = 2; } if(seeker3_health == 0) { sel = 3; } // reset seeker and update score when seekers health goes to zero if(sel != 0) { _enemy.reset_seeker(sel); _health.reset_seekerh(sel); _score = _score + 10; } } void RosenEngine::check_sh_health() { // set sel (select) as default 0 int sel = 0; // get the shooters health int shooter1_health = _health.get_shooterh(1); int shooter2_health = _health.get_shooterh(2); int shooter3_health = _health.get_shooterh(3); // set sel depending on if any shooters health falls below zero if(shooter1_health == 0) { sel = 1; } if(shooter2_health == 0) { sel = 2; } if(shooter3_health == 0) { sel = 3; } // reset shooter and update score when shooter health goes to zero if(sel != 0) { _enemy.reset_shooter(sel); _health.reset_shooterh(sel); _score = _score + 20; } } int RosenEngine::rand_no() { // seeds and returns a random number using the ctime library srand(time(NULL)); int rand_no = (rand() %45) + 1; return rand_no; } float RosenEngine::timer(int fps) { // using the amount of times run and the frames per second set the amount of // time past is calculated _times_run = _times_run + 1; float time_frame = 1.0f/fps; float time_elapsed = _times_run * time_frame; // printf("time elapsed = %f,time frame = %f, _times_run = %d\n",time_elapsed,time_frame,_times_run); return time_elapsed; } void RosenEngine::score(int points) { _score = _score + points; } bool RosenEngine::dead() { return _dead; } void RosenEngine::scaling(float time_elapsed) { // increases difficulty as game progresses if(time_elapsed == _wait_time) { // check if time elapsed is equal to the wit time _no_shooters = _no_shooters + 1; // update number of shooters and seekers after wait time _no_seekers = _no_seekers + 1; //increase wait time _enemy.sh_scaling(time_elapsed); _wait_time = _wait_time + 10.00; } // limit the number of seekers and number of shooters to 3 if(_no_shooters > 3) { _no_shooters = 3; } if(_no_seekers > 3) { _no_seekers = 3; } // set approriate enemy numbers _enemy.set_noshooters(_no_shooters); _enemy.set_noseekers(_no_seekers); // printf("time_elapsed = %f, no_shooters = %d, wait_time = %f\n",time_elapsed,_no_shooters,_wait_time); } void RosenEngine::game_over(N5110 &lcd) { // Display random tips after every loss _lore.display(lcd,rand_no()); } void RosenEngine::intro(N5110 &lcd) { // display intro _lore.intro(lcd); _intro = true; } void RosenEngine::disp_points(N5110 &lcd) { // display players points on screen char buffer[10]; sprintf(buffer,"%d",_score); lcd.printString(buffer,2,0); } Vector2D RosenEngine::get_enemynum() { // return the number of enemy shooters and seekers currently on play return{_no_shooters,_no_seekers}; } int RosenEngine::range(int x1, int y1, float x2, float y2) { // calculates average distance between two points float rangex = (abs(x1 - x2)); float rangey = (abs(y1 - y2)); int distance = floor((rangex+rangey)/2); return distance; } Vector2D RosenEngine::find_closest1() { // get the distance for all enemies int sh1 = range(_shipPos.x,_shipPos.y,_shooterPos[0].x,_shooterPos[0].y); int sh2 = range(_shipPos.x,_shipPos.y,_shooterPos[1].x,_shooterPos[1].y); int sh3 = range(_shipPos.x,_shipPos.y,_shooterPos[2].x,_shooterPos[2].y); int se1 = range(_shipPos.x,_shipPos.y,_seekerPos[0].x,_seekerPos[0].y); int se2 = range(_shipPos.x,_shipPos.y,_seekerPos[1].x,_seekerPos[1].y); int se3 = range(_shipPos.x,_shipPos.y,_seekerPos[2].x,_seekerPos[2].y); int close[6] = {sh1,sh2,sh3,se1,se2,se3}; // find index of the smallest element int index = 0; int smallest = close[0]; for(int i=0; i<6; i=i+1) { if(smallest>close[i]) { smallest=close[i]; index = i; } } // return the index, so we know what the closest enemy, and the distance to check its in range return {(index + 1),smallest}; } Vector2D RosenEngine::find_closest2(int index) { // return the position of the closest enemy if(index == 1 && _no_shooters >= 1) { return {_shooterPos[0].x,_shooterPos[0].y}; } if(index == 2 && _no_shooters >= 2) { return {_shooterPos[1].x,_shooterPos[1].y}; } if(index == 3 && _no_shooters >= 3) { return {_shooterPos[2].x,_shooterPos[2].y}; } if(index == 4 && _no_seekers >= 1 ) { return {_seekerPos[0].x,_seekerPos[0].y}; } if(index == 5 && _no_seekers >= 2) { return {_seekerPos[1].x,_seekerPos[1].y}; } if(index == 6 && _no_seekers >= 3) { return {_seekerPos[2].x,_seekerPos[2].y}; } } Vector2D RosenEngine::get_shipPos() { return{_shipPos}; }