ELEC2645 (2015/16)
/
el14af
Space Game
Revision 0:10704407da46, committed 2016-05-05
- Comitter:
- el14af
- Date:
- Thu May 05 10:21:22 2016 +0000
- Commit message:
- final awesome
Changed in this revision
diff -r 000000000000 -r 10704407da46 ESP.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ESP.cpp Thu May 05 10:21:22 2016 +0000 @@ -0,0 +1,2069 @@ +// +// Elec 2645 +// Embedded Systems Project +// 5 March 2016 +// Aleksander Filipiak + +#include "ESP.h" + + +// ---------------------------------------------------------------------------MAIN()----------------------------------------------------------------------------------------------------- + +int main() +{ + // initialise buttons + speed_button.mode(PullDown); + start_button.mode(PullDown); + pause_button.mode(PullDown); + pause_button.rise(&pause_isr); + + //initialise display + lcd.init(); + + //calibrate joystick + calibrateJoystick(); + + // print border + print_border(0,83,0,47); + + // position in menu, 0 = start game, 1 = help + bool position = 0; + + // attach joystick + pollJoystick.attach(&updateJoystick,0.05); + + + // menu + while (1) { + + // select menu item: start game + if (joystick.direction == UP) { + position = 0; + } + // help + else if (joystick. direction == DOWN) { + position = 1; + } + + //clear lcd + lcd.clear(); + + // print menu items + lcd.printString("START GAME",20,1); + lcd.printString("HELP",20,3); + + // print cursor at appropriate position + if (!position) { + lcd.drawRect(15,10,2,2,0); + } else { + lcd.drawRect(15,25,2,2,0); + } + + // refresh border + print_border(0,83,0,47); + // smaller ornamental border + print_border(2,81,2,45); + + // refresh screen + lcd.refresh(); + + // if either button is pressed and the help menu function is selected bring up the help menu + if ((start_button || speed_button) && position) { + + // outout variable + int output; + + // create array for counter + int help_counter [5] = {0,1,2,3,4}; + + // state variable + int state = 0; + + // help loop + while (1) { + + // check which state the counter is in and see which the next state should be next, + // depending on direction + switch(state) { + case 0: + switch(joystick.direction) { + case RIGHT: + state = 0; + break; + case LEFT: + state = 1; + break; + } + break; + // + case 1: + + switch(joystick.direction) { + case RIGHT: + state = 0; + break; + case LEFT: + state = 2; + break; + } + break; + case 2: + + switch(joystick.direction) { + case RIGHT: + state = 1; + break; + case LEFT: + state = 3; + break; + } + break; + case 3: + + switch(joystick.direction) { + case RIGHT: + state = 0; + break; + case LEFT: + state = 4; + break; + } + // last state brings the user back to the main menu + case 4: + break; + } + + // outout current state + output = help_counter[state]; + + lcd.clear(); + + // refresh border + print_border(0,83,0,47); + // smaller ornamental border + print_border(2,81,2,45); + + // print instructions based on counter output + if (output ==0) { + + // instructions + lcd.printString("USE",10,1); + lcd.printString("JOYSTICK",10,2); + lcd.printString("TO MOVE",10,3); + lcd.printString("SHIP",10,4); + } else if (output ==1) { + + // instructions + lcd.printString("START BUTTON:",5,1); + lcd.printString("PAUSE",10,2); + lcd.printString("SPEED BUTTON:",5,3); + lcd.printString("FASTER SHIP",10,4); + } else if (output ==2) { + + // instructions + lcd.drawRect(5,10,2,2,0); + lcd.printString("+ 8 seconds",15,1); + lcd.drawLine(5,27,7,27,1); + lcd.drawLine(6,26,6,28,1); + lcd.printString("- 5 seconds",15,3); + + } else if (output ==3) { + + // instructions + lcd.printString("DON'T LET",10,1); + lcd.printString("THE TIMER",10,2); + lcd.printString("RUN OUT!",10,3); + // 5th state breaks the loop and leads back to menu + } else if (output ==4) { + + break; + } + lcd.refresh(); + + //short delay + wait(0.3); + + } + } + + // if the button has been pressed and Start Game is selected, break the menu loop + // and continue to game initialisation + if ((start_button || speed_button) && !position) { + break; + } + + wait(0.1); + + } + + lcd.clear(); + + // print game border + print_border(0,83,8,47); + + // setup + setup_game(); + + lcd.refresh(); + + // flashing press start + while(1) { + + lcd.printString ("PRESS START",10,2); + + lcd.refresh(); + + wait(0.5); + + lcd.printString (" ",10,2); + + wait(0.3); + + // break loop when start button is pressed + if (start_button == 1) { + break; + } + } + + wait(0.5); + + // attach tickers: + + // ship + ship_mover.attach(&speed_change,0.03); // ship mover + //turrets + turret_mover.attach(&update_turrets,0.07); // turret mover + shooter.attach(&shoot,0.5); // shooter + // missles + missle_mover.attach(&update_missles,0.04); // missle mover + hit_checker.attach(&check_hit,0.04); // hit checker + // collectibles + collect_printer.attach(&print_collect,5.0); // collectible printer + collect_checker.attach(&check_collect,0.05); // collectible checker + collect_updater.attach(&update_collect,0.1); // collectible updater + collect_timer.attach(&collect_timeout,10.0); // collectible timer + // timer + timer.attach(&time_left,1.0); + + // reset timer + g_time_left = 30; + + // game loop + while(1) { + + + // pause loop + // if pause button is pressed + if (g_pause_flag) { + + g_pause_flag = 0; + + // detach tickers to stop gameplay + //ship + ship_mover.detach(); // ship mover + //turrets + turret_mover.detach(); // turret mover + shooter.detach(); // shooter + // missles + missle_mover.detach(); // missle mover + hit_checker.detach(); // hit checker + // collectibles + collect_printer.detach();// collectible printer + collect_checker.detach();// collectible checker + collect_updater.detach();// collectible updater + collect_timer.detach(); // collectible timer + // timer + timer.detach(); + + while(1) { + + + // flashing pause + lcd.printString(" ",25,2); + + wait(0.3); + + lcd.printString("PAUSE",25,2); + + wait(0.5); + + lcd.refresh(); + + // if the start button is pressed again game starts again + if (g_pause_flag) { + break; + } + + } + // reset flag + g_pause_flag = 0; + + // clear pause + lcd.printString(" ",25,2); + + // re-attach tickers to restart gameplay + // ship + ship_mover.attach(&speed_change,0.03); // ship mover + //turrets + turret_mover.attach(&update_turrets,0.07); // turret mover + shooter.attach(&shoot,0.5); // shooter + // missles + missle_mover.attach(&update_missles,0.04); // missle mover + hit_checker.attach(&check_hit,0.04); // hit checker + // collectibles + collect_printer.attach(&print_collect,5.0); // collectible printer + collect_checker.attach(&check_collect,0.05); // collectible checker + collect_updater.attach(&update_collect,0.1); // collectible updater + collect_timer.attach(&collect_timeout,10.0); // collectible timer + // timer + timer.attach(&time_left,1.0); + } + + // print game border + print_border(0,83,8,47); + + // if missle hits + if(g_hit_flag == 1) { + // reset missle flags in case missle hits again + missle_one.hit_flag = 0; + missle_two.hit_flag = 0; + missle_three.hit_flag = 0; + missle_four.hit_flag = 0; + missle_five.hit_flag = 0; + missle_six.hit_flag = 0; + + //take 5 seconds off the timer + g_time_left = g_time_left - 5; + + // print new time left + char buffer[14]; + int length = sprintf(buffer,"Time: %2d ",g_time_left); + if (length <= 14) // if string will fit on display + lcd.printString(buffer,16,0); + + // reset flag + g_hit_flag = 0; + } + // if collectible is collected + if(g_collect_flag) { + + // add 8 seconds to timer + g_time_left = g_time_left +8; + + // print new time left + char buffer[14]; + int length = sprintf(buffer,"Time: %2d ",g_time_left); + if (length <= 14) // if string will fit on display + lcd.printString(buffer,16,0); + + // reset flag + g_collect_flag = 0; + } + + //refresh screen + lcd.refresh(); + + // break loop if timer runs out + if (g_time_left < 0) { + + break; + + } + } + // detach all tickers + + // ship + ship_mover.detach(); // ship mover + //turrets + turret_mover.detach(); // turret mover + shooter.detach(); // shooter + // missles + missle_mover.detach(); // missle mover + hit_checker.detach(); // hit checker + // collectibles + collect_printer.detach();// collectible printer + collect_checker.detach();// collectible checker + collect_updater.detach();// collectible updater + collect_timer.detach(); // collectible timer + // timer + timer.detach(); + + lcd.clear(); + + // screen border + print_border(0,83,0,47); + // smaller ornamental border + print_border(2,81,2,45); + + // print score + lcd.printString("SCORE: ",23,2); + char buffer[14]; + int length = sprintf(buffer," %2d ",g_score); + lcd.printString(buffer,23,3); + +} + +// ---------------------------------------------------------------------------FUNCTION PROTOTYPES----------------------------------------------------------------------------------------- + +void pause_isr () +{ + + g_pause_flag = 1; +} + +// read default positions of the joystick to calibrate later readings +void calibrateJoystick() +{ + //button.mode(PullDown); + // must not move during calibration + joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly) + joystick.y0 = yPot; +} +// read and update position of the joystick +void updateJoystick() +{ + // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred) + joystick.x = xPot - joystick.x0; + joystick.y = yPot - joystick.y0; + // read button state + //joystick.button = button; + + // calculate direction depending on x,y values + // tolerance allows a little lee-way in case joystick not exactly in the stated direction + if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { + joystick.direction = CENTRE; + } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { + joystick.direction = UP; + } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { + joystick.direction = DOWN; + } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { + joystick.direction = RIGHT; + } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { + joystick.direction = LEFT; + } else { + joystick.direction = UNKNOWN; + } + + // set flag for printing + printFlag = 1; +} + +// function for creating border +void print_border(int Xstart, int Xend, int Ystart, int Yend) +{ + + for (int i=Xstart; i<Xend+1; i++) { + lcd.setPixel(i,Ystart); + lcd.setPixel(i,Yend); + } + for (int j=Ystart; j<Yend+1; j++) { + lcd.setPixel(Xstart,j); + lcd.setPixel(Xend,j); + } +} + +// setup game screen for current level +void setup_game() +{ + + // print ship in the middle of screen pointing up + +// set up default x/y coordinate of the centre pixel of the ship, in the middle +// of the display, with the dwfault direction of UP. properties are defined within +// the Ship struct. + ship.x = 42; + ship.y = 35; + ship.direction = UP; + +//print ship around the x/y centre coordinate + + //centre + lcd.drawLine(ship.x,ship.y-2,ship.x,ship.y+1,1); + // centre left + lcd.drawLine(ship.x-1,ship.y-1,ship.x-1,ship.y+2,1); + // left engine + lcd.drawLine(ship.x-2,ship.y+1,ship.x-2,ship.y+2,1); + // centre right + lcd.drawLine(ship.x+1,ship.y-1,ship.x+1,ship.y+2,1); + // right engine + lcd.drawLine(ship.x+2,ship.y+1,ship.x+2,ship.y+2,1); + + + // turret setup + // sets the default parameters for the current level + + // top turret setup + top_turret.position = 62; + top_turret.direction = LEFT; + + // print turret at new position + lcd.drawRect(top_turret.position-2,9,4,2,1); + lcd.clearPixel(top_turret.position,11); + + + // bottom turret setup + bottom_turret.position = 21; + bottom_turret.direction = RIGHT; + + // print turret at new position + lcd.drawRect(bottom_turret.position - 2,44,4,2,1); + lcd.clearPixel(bottom_turret.position,44); + + + // left turret setup + left_turret.position = 16; + left_turret.direction = DOWN; + + // print turret at new position + lcd.drawRect(1,left_turret.position-2,2,4,1); + lcd.clearPixel(3,left_turret.position); + + + + // right turret setup + right_turret.position = 31; + right_turret.direction = UP; + + // print turret at new position + lcd.drawRect(80,right_turret.position-2,2,4,1); + lcd.clearPixel(80,right_turret.position); + + +} + + +void speed_change() +{ + // increment the ship counter every time the ship moves + g_ship_counter ++; + + // if speed button is not pressed and counter number is divisible by 3 + if (speed_button == 0 && g_ship_counter % 3 == 0) { + + update_ship(); + } + // else if speed_button is pressed + else if (speed_button == 1) { + + // update ship with every repetition + update_ship(); + + } +} + +// update ship's position based on jostick controls +void update_ship () +{ + + +// clear ship at current position of x/y coordinates. since the ship has symetrical + + lcd.drawRect(ship.x-2,ship.y-2,4,4,2); + + + +// update ship direction variable in struct based on position of joystick + if (joystick.direction == UP) { + + ship.direction = UP; + } + if (joystick.direction == DOWN) { + + ship.direction = DOWN; + } + if (joystick.direction == RIGHT) { + + ship.direction = RIGHT; + } + if (joystick.direction == LEFT) { + + ship.direction = LEFT; + } + // don't update position if joystick position is unchanged, or is unknown. + // i.e. ship continues to fly in a straight line + if (joystick.direction == CENTRE || joystick.direction == UNKNOWN) { + + ship.direction = ship.direction; + } + +// Print ship in new position based on the four possible directions that the ship could be traveling in +// i.e. UP, DOWN, LEFT or RIGHT. The manitude of the shift of the x/y centre of the ship depends on +// the state of the speed_button: shift by 1 pixel for standard movement and by 3 pixels for faster +// movement. The newly printed ship points in the direction of travel. + + if (ship.direction == UP) { + + // print ship 1 pixel higher + ship.y = ship.y - 1; + +// print new ship + + //centre + lcd.drawLine(ship.x,ship.y-2,ship.x,ship.y+1,1); + // centre left + lcd.drawLine(ship.x-1,ship.y-1,ship.x-1,ship.y+2,1); + // left engine + lcd.drawLine(ship.x-2,ship.y+1,ship.x-2,ship.y+2,1); + // centre right + lcd.drawLine(ship.x+1,ship.y-1,ship.x+1,ship.y+2,1); + // right engine + lcd.drawLine(ship.x+2,ship.y+1,ship.x+2,ship.y+2,1); + } + + if (ship.direction == DOWN) { + + // print ship 1 pixel lower + ship.y = ship.y + 1; + +//print new ship + + // centre + lcd.drawLine(ship.x,ship.y-1,ship.x,ship.y+2,1); + // centre left + lcd.drawLine(ship.x-1,ship.y+1,ship.x-1,ship.y-2,1); + // left engine + lcd.drawLine(ship.x-2,ship.y-1,ship.x-2,ship.y-2,1); + // centre right + lcd.drawLine(ship.x+1,ship.y+1,ship.x+1,ship.y-2,1); + // right engine + lcd.drawLine(ship.x+2,ship.y-1,ship.x+2,ship.y-2,1); + + } + + if (ship.direction == LEFT) { + + // print ship 1 pixel to the left + ship.x = ship.x + 1; + +//print new ship + + // centre + lcd.drawLine(ship.x-1,ship.y,ship.x+2,ship.y,1); + // upper centre + lcd.drawLine(ship.x-2,ship.y-1,ship.x+1,ship.y-1,1); + // top engine + lcd.drawLine(ship.x-2,ship.y-2,ship.x-1,ship.y-2,1); + // lower centre + lcd.drawLine(ship.x-2,ship.y+1,ship.x+1,ship.y+1,1); + // bottom engine + lcd.drawLine(ship.x-2,ship.y+2,ship.x-1,ship.y+2,1); + + } + + if (ship.direction == RIGHT) { + + // print ship 1 pixel right + ship.x = ship.x - 1; + + +//print new ship + + // centre + lcd.drawLine(ship.x-2,ship.y,ship.x+1,ship.y,1); + // upper centre + lcd.drawLine(ship.x-1,ship.y-1,ship.x+2,ship.y-1,1); + // top engine + lcd.drawLine(ship.x+1,ship.y-2,ship.x+2,ship.y-2,1); + // lower centre + lcd.drawLine(ship.x-1,ship.y+1,ship.x+2,ship.y+1,1); + // bottom engine + lcd.drawLine(ship.x+1,ship.y+2,ship.x+2,ship.y+2,1); + + } + // limit ship position to the game borders: + // X MIN + if (ship.x < 2) { + ship.x = 2; + } + // X MAX + if (ship.x > 81) { + ship.x = 81; + } + // Y MIN + if (ship.y < 10) { + ship.y = 10; + } + // Y MAX + if (ship.y > 45) { + ship.y = 45; + } +} + +// update position of top turret +void update_turrets () +{ + + // update top turret + + // clear turret at current position + lcd.drawRect(top_turret.position-2,9,4,2,2); + + // if the turret has reached the screen boundry, change the direction + if (top_turret.position == 3) { + top_turret.direction = RIGHT; + } + if (top_turret.position == 80) { + top_turret.direction = LEFT; + } + + // shift the position of the centre pixel of the turret in the dirction of movement + if (top_turret.direction == LEFT) { + top_turret.position -- ; + } else if (top_turret.direction == RIGHT) { + top_turret.position ++ ; + } + + // print turret at new position + lcd.drawRect(top_turret.position-2,9,4,2,1); + lcd.clearPixel(top_turret.position,11); + + + + //update bottom turret + + //clear turret at current position + lcd.drawRect(bottom_turret.position - 2,44,4,2,2); + + // if the turret has reached the screen boundry, change the direction + if (bottom_turret.position == 3) { + bottom_turret.direction = RIGHT; + } + if (bottom_turret.position == 80) { + bottom_turret.direction = LEFT; + } + + // shift the position of the centre pixel of the turret in the dirction of movement + if (bottom_turret.direction == LEFT) { + bottom_turret.position -- ; + } else if(bottom_turret.direction == RIGHT) { + bottom_turret.position ++ ; + } + + //print turret at new position + lcd.drawRect(bottom_turret.position - 2,44,4,2,1); + lcd.clearPixel(bottom_turret.position,44); + + + + // update left turret + + // clear turret at current position + lcd.drawRect(1,left_turret.position-2,2,4,2); + + // if the turret has reached the screen boundry, change the direction + + if (left_turret.position == 10) { + left_turret.direction = DOWN; + } + if (left_turret.position == 44) { + left_turret.direction = UP; + } + + // shift the position of the centre pixel of the turret in the dirction of movement + if (left_turret.direction == UP) { + left_turret.position -- ; + } else if (left_turret.direction == DOWN) { + left_turret.position ++ ; + } + + // print turret at new position + lcd.drawRect(1,left_turret.position-2,2,4,1); + lcd.clearPixel(3,left_turret.position); + + + + // update right turret + + // clear turret at current position + lcd.drawRect(80,right_turret.position-2,2,4,2); + + // if the turret has reached the screen boundry, change the direction + + if (right_turret.position == 10) { + right_turret.direction = DOWN; + } + if (right_turret.position == 44) { + right_turret.direction = UP; + } + + // shift the position of the centre pixel of the turret in the dirction of movement + if (right_turret.direction == UP) { + right_turret.position -- ; + } else if (right_turret.direction == DOWN) { + right_turret.position ++ ; + } + + // print turret at new position + lcd.drawRect(80,right_turret.position-2,2,4,1); + lcd.clearPixel(80,right_turret.position); + + + lcd.refresh(); + +} + +//function for firing missles +void shoot() +{ + + // generates a pseudo-random value between 0 and 99 for each turret. + srand(time(NULL)); + int top_shoot = rand() %100+1; + int bottom_shoot = rand() %100+1; + int left_shoot = rand() %100+1; + int right_shoot = rand() %100+1; + + // 20% chance for each turret to fire a missle. if random value is less than 20 the turret fires + // and the turret's shoot property is set to 1. the process is the same for each of the 4 turrets. + if (top_shoot < 20 ) { + + //change shoot varialbe in turret struct + top_turret.shoot = 1; + + // search for an inactive missle struct to assign the missle to. if none of the missle + // struct as available, i.e. there are already 6 missles on screen, the turret does not + // fire. + if (!missle_one.active) { // if missle is available + missle_one.active = 1; // set missle to active + missle_one.x = top_turret.position; // set the x-axis position of the missle equal to the turret's position + missle_one.y = 10; // the Y coordinate is set to 8 to account for game border and turret + missle_one.direction = DOWN; // set the direction the missle should travel in + } + // steps are repeated in case of other missle structs being used + else if (!missle_two.active) { + missle_two.active = 1; + missle_two.x = top_turret.position; + missle_two.y = 10; + missle_two.direction = DOWN; + } else if (!missle_three.active) { + missle_three.active = 1; + missle_three.x = top_turret.position; + missle_three.y = 10; + missle_three.direction = DOWN; + } else if (!missle_four.active) { + missle_four.active = 1; + missle_four.x = top_turret.position; + missle_four.y = 10; + missle_four.direction = DOWN; + } else if (!missle_five.active) { + missle_five.active = 1; + missle_five.x = top_turret.position; + missle_five.y = 10; + missle_five.direction = DOWN; + } else if (!missle_six.active) { + missle_six.active = 1; + missle_six.x = top_turret.position; + missle_six.y = 10; + missle_six.direction = DOWN; + } else { + top_turret.shoot = 0; + } + + } + // whole process is identical for the other three turrets. the only changes are the direction assigned + // to the missle when it fires, and whether the position of the turret dictates the x or y starting + // position of the missle + + // bottom turret + if (bottom_shoot < 20 ) { + + bottom_turret.shoot = 1; + + if (!missle_one.active) { // if missle is available + missle_one.active = 1; // set missle to active + missle_one.x = bottom_turret.position; // set the X-axis position of the missle equal to the turret's position + missle_one.y = 45; // the Y coordinate is set to 45 to account for game border and turret + missle_one.direction = UP; // set the direction the missle should travel in + } + // steps are repeated in case of other missle structs being used + else if (!missle_two.active) { + missle_two.active = 1; + missle_two.x = bottom_turret.position; + missle_two.y = 45; + missle_two.direction = UP; + } else if (!missle_three.active) { + missle_three.active = 1; + missle_three.x = bottom_turret.position; + missle_three.y = 45; + missle_three.direction = UP; + } else if (!missle_four.active) { + missle_four.active = 1; + missle_four.x = bottom_turret.position; + missle_four.y = 45; + missle_four.direction = UP; + } else if (!missle_five.active) { + missle_five.active = 1; + missle_five.x = bottom_turret.position; + missle_five.y = 45; + missle_five.direction = UP; + } else if (!missle_six.active) { + missle_six.active = 1; + missle_six.x = bottom_turret.position; + missle_six.y = 45; + missle_six.direction = UP; + } else { + bottom_turret.shoot = 0; + } + + } + // left turret + if (left_shoot < 20 ) { + + left_turret.shoot = 1; + + if (!missle_one.active) { + missle_one.active = 1; + missle_one.x = 3; // the X coordinate is set to 3 to account for game border and turret + missle_two.y = left_turret.position; // set the Y-axis position of the missle equal to the turret's position + + missle_one.direction = RIGHT; + } else if (!missle_two.active) { + missle_two.active = 1; + missle_two.x = 3; + missle_two.y = left_turret.position; + missle_two.direction = RIGHT; + } else if (!missle_three.active) { + missle_three.active = 1; + missle_three.x = 3; + missle_three.y = left_turret.position; + missle_three.direction = RIGHT; + } else if (!missle_four.active) { + missle_four.active = 1; + missle_four.x = 3; + missle_four.y = left_turret.position; + missle_four.direction = RIGHT; + } else if (!missle_five.active) { + missle_five.active = 1; + missle_five.x = 3; + missle_five.y = left_turret.position; + missle_five.direction = RIGHT; + } else if (!missle_six.active) { + missle_six.active = 1; + missle_six.x = 3; + missle_six.y = left_turret.position; + missle_six.direction = RIGHT; + } else { + left_turret.shoot = 0; + } + + } + // right turret + if (right_shoot < 20 ) { + + left_turret.shoot = 1; + + if (!missle_one.active) { + missle_one.active = 1; + missle_one.x = 81; // the X coordinate is set to 81 to account for game border and turret + missle_one.y = right_turret.position; // set the Y-axis position of the missle equal to the turret's position + missle_one.direction = LEFT; + } else if (!missle_two.active) { + missle_two.active = 1; + missle_two.x = 81; + missle_two.y = right_turret.position; + missle_two.direction = LEFT; + } else if (!missle_three.active) { + missle_three.active = 1; + missle_three.x = 81; + missle_three.y = right_turret.position; + missle_three.direction = LEFT; + } else if (!missle_four.active) { + missle_four.active = 1; + missle_four.x = 81; + missle_four.y = right_turret.position; + missle_four.direction = LEFT; + } else if (!missle_five.active) { + missle_five.active = 1; + missle_five.x = 81; + missle_five.y = right_turret.position; + missle_five.direction = LEFT; + } else if (!missle_six.active) { + missle_six.active = 1; + missle_six.x = 81; + missle_six.y = right_turret.position; + missle_six.direction = LEFT; + } else { + right_turret.shoot = 0; + } + + } + +} + +// track position of currently flying missles, update their position and detect hits. +void update_missles () +{ + // only preform operations if missle is active for efficiency + if (missle_one.active) { + + //clear missle at current position + // centre + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + + // set new position of missle based on direction of travel + if (missle_one.direction == UP) { + missle_one.y -- ; + } + if (missle_one.direction == DOWN) { + missle_one.y ++ ; + } + if (missle_one.direction == LEFT) { + missle_one.x -- ; + } + if (missle_one.direction == RIGHT) { + missle_one.x ++ ; + } + + //draw missle at new position + lcd.drawLine(missle_one.x - 1,missle_one.y,missle_one.x + 1,missle_one.y,1); + lcd.drawLine(missle_one.x,missle_one.y - 1,missle_one.x,missle_one.y + 1,1); + + + } + + // the function then repeats process for any other active missles + + if (missle_two.active) { + //clear missle at current position + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + + // set new position of missle based on direction of travel + if (missle_two.direction == UP) { + missle_two.y -- ; + } + if (missle_two.direction == DOWN) { + missle_two.y ++ ; + } + if (missle_two.direction == LEFT) { + missle_two.x -- ; + } + if (missle_two.direction == RIGHT) { + missle_two.x ++ ; + } + + //draw missle at new position + lcd.drawLine(missle_two.x - 1,missle_two.y,missle_two.x + 1,missle_two.y,1); + lcd.drawLine(missle_two.x,missle_two.y - 1,missle_two.x,missle_two.y + 1,1); + + + } + if (missle_three.active) { + //clear missle at current position + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + + // set new position of missle based on direction of travel + if (missle_three.direction == UP) { + missle_three.y -- ; + } + if (missle_three.direction == DOWN) { + missle_three.y ++ ; + } + if (missle_three.direction == LEFT) { + missle_three.x -- ; + } + if (missle_three.direction == RIGHT) { + missle_three.x ++ ; + } + + //draw missle at new position + lcd.drawLine(missle_three.x - 1,missle_three.y,missle_three.x + 1,missle_three.y,1); + lcd.drawLine(missle_three.x,missle_three.y - 1,missle_three.x,missle_three.y + 1,1); + + } + if (missle_four.active) { + //clear missle at current position + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + + // set new position of missle based on direction of travel + if (missle_four.direction == UP) { + missle_four.y -- ; + } + if (missle_four.direction == DOWN) { + missle_four.y ++ ; + } + if (missle_four.direction == LEFT) { + missle_four.x -- ; + } + if (missle_four.direction == RIGHT) { + missle_four.x ++ ; + } + + //draw missle at new position + lcd.drawLine(missle_four.x - 1,missle_four.y,missle_four.x + 1,missle_four.y,1); + lcd.drawLine(missle_four.x,missle_four.y - 1,missle_four.x,missle_four.y + 1,1); + + } + if (missle_five.active) { + //clear missle at current position + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + + // set new position of missle based on direction of travel + if (missle_five.direction == UP) { + missle_five.y -- ; + } + if (missle_five.direction == DOWN) { + missle_five.y ++ ; + } + if (missle_five.direction == LEFT) { + missle_five.x -- ; + } + if (missle_five.direction == RIGHT) { + missle_five.x ++ ; + } + + //draw missle at new position + lcd.drawLine(missle_five.x - 1,missle_five.y,missle_five.x + 1,missle_five.y,1); + lcd.drawLine(missle_five.x,missle_five.y - 1,missle_five.x,missle_five.y + 1,1); + + + } + if (missle_six.active) { + //clear missle at current position + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + + // set new position of missle based on direction of travel + if (missle_six.direction == UP) { + missle_six.y -- ; + } + if (missle_six.direction == DOWN) { + missle_six.y ++ ; + } + if (missle_six.direction == LEFT) { + missle_six.x -- ; + } + if (missle_six.direction == RIGHT) { + missle_six.x ++ ; + } + + //draw missle at new position + lcd.drawLine(missle_six.x - 1,missle_six.y,missle_six.x + 1,missle_six.y,1); + lcd.drawLine(missle_six.x,missle_six.y - 1,missle_six.x,missle_six.y + 1,1); + + + + } +} + +// detect hits missle expires +void check_hit () +{ + // only preform operations if missle is active for efficiency + if (missle_one.active) { + + + if (ship.direction == UP) { + // check if the missle is within the x_axis constraints of the hit box + // the structure : if missle x coordinate is greater than the top right pixel of hit box... + // AND + // missle x coordinate is less than top right pixel of hit box + width of the hit box... + // then the missle is in the x constraints. + if ( (missle_one.x > ship.x - 2 ) && (missle_one.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_one.y > ship.y - 2 ) && (missle_one.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + missle_one.active = 0; + // set hit flag for missle 1. + missle_one.hit_flag = 1; + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + } + } + // the process is repeated for the different directions of travel, with a different hitbox shape: + // down + if (ship.direction == DOWN) { + if ( (missle_one.x > ship.x - 2 ) && (missle_one.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_one.y > ship.y - 3 ) && (missle_one.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_one.active = 0; + // set hit flag for missle 1. + missle_one.hit_flag = 1; + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + } + } + // left + if (ship.direction == LEFT) { + if ( (missle_one.x > ship.x - 3 ) && (missle_one.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_one.y > ship.y - 2 ) && (missle_one.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_one.active = 0; + // set hit flag for missle 1. + missle_one.hit_flag = 1; + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + } + } + // right + if (ship.direction == RIGHT) { + if ( (missle_one.x > ship.x - 2 ) && (missle_one.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_one.y > ship.y - 2 ) && (missle_one.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_one.active = 0; + // set hit flag for missle 1. + missle_one.hit_flag = 1; + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + } + } + + // detect missle expires + // depending on the direction of flight, if the missle reaches the border without coming in contact with the ship. + // the missle is set to inactive + + if (missle_one.direction == UP) { + if (missle_one.y == 10) { + missle_one.active = 0; + + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + + } + if (missle_one.direction == DOWN) { + if (missle_one.y == 45) { + missle_one.active = 0; + + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + + } + if (missle_one.direction == LEFT) { + if (missle_one.x == 2 ) { + missle_one.active = 0; + + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + + } + if (missle_one.direction == RIGHT) { + if (missle_one.x == 80 ) { + missle_one.active = 0; + + //clear missle + lcd.drawRect(missle_one.x-1,missle_one.y-1,2,2,2); + } + + } + } + // only preform operations if missle is active for efficiency + if (missle_two.active) { + if (ship.direction == UP) { + //check if the ship is within the x_axis constraints of the hit box + // the structure : if missle x coordinate is greater than the top right pixel of hit box... + // AND + // missle x coordinate is less than top right pixel of hit box + width of the hit box... + // then the missle is in the x constraints. + if ( (missle_two.x > ship.x - 2 ) && (missle_two.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_two.y > ship.y - 2 ) && (missle_two.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + missle_two.active = 0; + // set hit flag for missle 1. + missle_two.hit_flag = 1; + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + } + } + // the process is repeated for the different directions of travel, with a different hitbox shape + if (ship.direction == DOWN) { + if ( (missle_two.x > ship.x - 2 ) && (missle_two.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_two.y > ship.y - 3 ) && (missle_two.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_two.active = 0; + // set hit flag for missle 1. + missle_two.hit_flag = 1; + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + } + } + if (ship.direction == LEFT) { + if ( (missle_two.x > ship.x - 2 ) && (missle_two.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_two.y > ship.y - 2 ) && (missle_two.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_two.active = 0; + // set hit flag for missle 1. + missle_two.hit_flag = 1; + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + } + } + if (ship.direction == RIGHT) { + if ( (missle_two.x > ship.x - 3 ) && (missle_two.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_two.y > ship.y - 2 ) && (missle_two.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_two.active = 0; + // set hit flag for missle 1. + missle_two.hit_flag = 1; + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + } + } + + // detect missle expires + // depending on the direction of flight, if the missle reaches the border without coming in contact with the ship. + // the missle is set to inactive + + if (missle_two.direction == UP) { + if (missle_two.y == 10) { + missle_two.active = 0; + + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + + } + if (missle_two.direction == DOWN) { + if (missle_two.y == 44) { + missle_two.active = 0; + + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + + } + if (missle_two.direction == LEFT) { + if (missle_two.x == 2 ) { + missle_two.active = 0; + + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + + } + if (missle_two.direction == RIGHT) { + if (missle_two.x == 80 ) { + missle_two.active = 0; + + //clear missle + lcd.drawRect(missle_two.x-1,missle_two.y-1,2,2,2); + } + + } + } + // only preform operations if missle is active for efficiency + if (missle_three.active) { + + if (ship.direction == UP) { + //check if the ship is within the x_axis constraints of the hit box + // the structure : if missle x coordinate is greater than the top right pixel of hit box... + // AND + // missle x coordinate is less than top right pixel of hit box + width of the hit box... + // then the missle is in the x constraints. + if ( (missle_three.x > ship.x - 2 ) && (missle_three.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_three.y > ship.y - 2 ) && (missle_three.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + missle_three.active = 0; + // set hit flag for missle 1. + missle_three.hit_flag = 1; + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + } + } + // the process is repeated for the different directions of travel, with a different hitbox shape + if (ship.direction == DOWN) { + if ( (missle_three.x > ship.x - 2 ) && (missle_three.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_three.y > ship.y - 3 ) && (missle_three.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_three.active = 0; + // set hit flag for missle 1. + missle_three.hit_flag = 1; + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + } + } + if (ship.direction == LEFT) { + if ( (missle_three.x > ship.x - 2 ) && (missle_three.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_three.y > ship.y - 2 ) && (missle_three.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_three.active = 0; + // set hit flag for missle 1. + missle_three.hit_flag = 1; + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + } + } + if (ship.direction == RIGHT) { + if ( (missle_three.x > ship.x - 3 ) && (missle_three.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_three.y > ship.y - 2) && (missle_three.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_three.active = 0; + // set hit flag for missle 1. + missle_three.hit_flag = 1; + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + } + } + + // detect missle expires + // depending on the direction of flight, if the missle reaches the border without coming in contact with the ship. + // the missle is set to inactive + + if (missle_three.direction == UP) { + if (missle_three.y == 10) { + missle_three.active = 0; + + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + + } + if (missle_three.direction == DOWN) { + if (missle_three.y == 44) { + missle_three.active = 0; + + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + + } + if (missle_three.direction == LEFT) { + if (missle_three.x == 2 ) { + missle_three.active = 0; + + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + + } + if (missle_three.direction == RIGHT) { + if (missle_three.x == 80 ) { + missle_three.active = 0; + + //clear missle + lcd.drawRect(missle_three.x-1,missle_three.y-1,2,2,2); + } + + } + + } + // only preform operations if missle is active for efficiency + if (missle_four.active) { + if (ship.direction == UP) { + //check if the ship is within the x_axis constraints of the hit box + // the structure : if missle x coordinate is greater than the top right pixel of hit box... + // AND + // missle x coordinate is less than top right pixel of hit box + width of the hit box... + // then the missle is in the x constraints. + if ( (missle_four.x > ship.x - 2 ) && (missle_four.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_four.y > ship.y - 2 ) && (missle_four.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + missle_four.active = 0; + // set hit flag for missle 1. + missle_four.hit_flag = 1; + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + } + } + // the process is repeated for the different directions of travel, with a different hitbox shape + if (ship.direction == DOWN) { + if ( (missle_four.x > ship.x - 2 ) && (missle_four.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_four.y > ship.y - 3 ) && (missle_four.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_four.active = 0; + // set hit flag for missle 1. + missle_four.hit_flag = 1; + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + } + } + if (ship.direction == LEFT) { + if ( (missle_four.x > ship.x - 2 ) && (missle_four.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_four.y > ship.y - 2) && (missle_four.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_four.active = 0; + // set hit flag for missle 1. + missle_four.hit_flag = 1; + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + } + } + if (ship.direction == RIGHT) { + if ( (missle_four.x > ship.x - 3 ) && (missle_four.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_four.y > ship.y - 2 ) && (missle_four.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_four.active = 0; + // set hit flag for missle 1. + missle_four.hit_flag = 1; + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + } + } + + // detect missle expires + // depending on the direction of flight, if the missle reaches the border without coming in contact with the ship. + // the missle is set to inactive + + if (missle_four.direction == UP) { + if (missle_four.y == 10) { + missle_four.active = 0; + + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + + } + if (missle_four.direction == DOWN) { + if (missle_four.y == 44) { + missle_four.active = 0; + + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + + } + if (missle_four.direction == LEFT) { + if (missle_four.x == 2 ) { + missle_four.active = 0; + + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + + } + if (missle_four.direction == RIGHT) { + if (missle_four.x == 80 ) { + missle_four.active = 0; + + //clear missle + lcd.drawRect(missle_four.x-1,missle_four.y-1,2,2,2); + } + + } + } + // only preform operations if missle is active for efficiency + if (missle_five.active) { + if (ship.direction == UP) { + //check if the ship is within the x_axis constraints of the hit box + // the structure : if missle x coordinate is greater than the top right pixel of hit box... + // AND + // missle x coordinate is less than top right pixel of hit box + width of the hit box... + // then the missle is in the x constraints. + if ( (missle_five.x > ship.x - 2 ) && (missle_five.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_five.y > ship.y - 2 ) && (missle_five.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + missle_five.active = 0; + // set hit flag for missle 1. + missle_five.hit_flag = 1; + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + } + } + // the process is repeated for the different directions of travel, with a different hitbox shape + if (ship.direction == DOWN) { + if ( (missle_five.x > ship.x - 2 ) && (missle_five.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_five.y > ship.y - 3 ) && (missle_five.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_five.active = 0; + // set hit flag for missle 1. + missle_five.hit_flag = 1; + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + } + } + if (ship.direction == LEFT) { + if ( (missle_five.x > ship.x - 2 ) && (missle_five.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_five.y > ship.y - 2 ) && (missle_five.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_five.active = 0; + // set hit flag for missle 1. + missle_five.hit_flag = 1; + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + } + } + if (ship.direction == RIGHT) { + if ( (missle_five.x > ship.x - 3 ) && (missle_five.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_five.y > ship.y - 2 ) && (missle_five.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_five.active = 0; + // set hit flag for missle 1. + missle_five.hit_flag = 1; + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + } + } + + // detect missle expires + // depending on the direction of flight, if the missle reaches the border without coming in contact with the ship. + // the missle is set to inactive + + if (missle_five.direction == UP) { + if (missle_five.y == 10) { + missle_five.active = 0; + + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + + } + if (missle_five.direction == DOWN) { + if (missle_five.y == 44) { + missle_five.active = 0; + + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + + } + if (missle_five.direction == LEFT) { + if (missle_five.x == 2 ) { + missle_five.active = 0; + + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + + } + if (missle_five.direction == RIGHT) { + if (missle_five.x == 80 ) { + missle_five.active = 0; + + //clear missle + lcd.drawRect(missle_five.x-1,missle_five.y-1,2,2,2); + } + + } + + } + // only preform operations if missle is active for efficiency + if (missle_six.active) { + if (ship.direction == UP) { + //check if the ship is within the x_axis constraints of the hit box + // the structure : if missle x coordinate is greater than the top right pixel of hit box... + // AND + // missle x coordinate is less than top right pixel of hit box + width of the hit box... + // then the missle is in the x constraints. + if ( (missle_six.x > ship.x - 2 ) && (missle_six.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_six.y > ship.y - 2 ) && (missle_six.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + missle_six.active = 0; + // set hit flag for missle 1. + missle_six.hit_flag = 1; + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + } + } + // the process is repeated for the different directions of travel, with a different hitbox shape + if (ship.direction == DOWN) { + if ( (missle_six.x > ship.x - 2) && (missle_six.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_six.y > ship.y - 3 ) && (missle_six.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_six.active = 0; + // set hit flag for missle 1. + missle_six.hit_flag = 1; + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + } + } + if (ship.direction == LEFT) { + if ( (missle_six.x > ship.x - 2 ) && (missle_six.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_six.y > ship.y - 2 ) && (missle_six.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_six.active = 0; + // set hit flag for missle 1. + missle_six.hit_flag = 1; + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + } + } + if (ship.direction == RIGHT) { + if ( (missle_six.x > ship.x - 3 ) && (missle_six.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (missle_six.y > ship.y - 2 ) && (missle_six.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + missle_six.active = 0; + // set hit flag for missle 1. + missle_six.hit_flag = 1; + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + } + } + + // detect missle expires + // depending on the direction of flight, if the missle reaches the border without coming in contact with the ship. + // the missle is set to inactive + + if (missle_six.direction == UP) { + if (missle_six.y == 10) { + missle_six.active = 0; + + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + + } + if (missle_six.direction == DOWN) { + if (missle_six.y == 44) { + missle_six.active = 0; + + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + + } + if (missle_six.direction == LEFT) { + if (missle_six.x == 2 ) { + missle_six.active = 0; + + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + + } + if (missle_six.direction == RIGHT) { + if (missle_six.x == 80 ) { + missle_six.active = 0; + + //clear missle + lcd.drawRect(missle_six.x-1,missle_six.y-1,2,2,2); + } + + } + } + + //if any of the missles have hit a flag is raised + if (missle_one.hit_flag == 1) { + g_hit_flag = 1; + } + if (missle_two.hit_flag == 1) { + g_hit_flag = 1; + } + if (missle_three.hit_flag == 1) { + g_hit_flag = 1; + } + if (missle_four.hit_flag == 1) { + g_hit_flag = 1; + } + if (missle_five.hit_flag == 1) { + g_hit_flag = 1; + } + if (missle_six.hit_flag == 1) { + g_hit_flag = 1; + } + +} +// raises flag for collectible timeout +void collect_timeout () +{ + g_collect_timeout_flag = 1; + +} +//prints collectible +void print_collect () +{ + // function first determines what collectible is free to be allocated, and if either collectible has expired + + bool collect_free; // variable for determining which collectible struct is free, 0 for collec_one and 1 for collect_two. + // determined by if statments below + + // if both collectibles are active + if (collect_one.active && collect_two.active) { + + // if either collectible has expired + if (g_collect_timeout_flag == 1) { + + // if collect_one has expired + if (!g_what_expired) { + // set to free + collect_free = 0; + + // reset collect_one + collect_one.active = 0; + + //clear collectible + lcd.drawRect(collect_one.x-1,collect_one.y-1,2,2,2); + + //reset timeout flag + g_collect_timeout_flag = 0; + + //change the next collectible to expire + g_what_expired = 1; + } + // if collect_two has expired + else { + // set to free + collect_free = 1; + + // reset collect_two + collect_two.active = 0; + + //clear collectible + lcd.drawRect(collect_two.x-1,collect_two.y-1,2,2,2); + + // reset timeout flag + g_collect_timeout_flag = 0; + + //change the next collectible to expire + g_what_expired = 0; + } + } + } + // if collect_two has been collected, or has not been allocated yet + else if (collect_one.active && !collect_two.active) { + + // set collect_two to free + collect_free = 1; + + } + // if collect_one has been collected, or has not been allocated yet + else if (!collect_one.active && collect_two.active) { + + // set_collect_one to free + collect_free = 0; + + } + // if neither collect_one or collect_two have been assigned, or both have been collected + else if (!collect_one.active && !collect_two.active) { + + // set collect_one to free + collect_free = 0; + + } + + // reset rand() seed + srand(time(NULL)); + + // the function then allocates a new position to whatever collectible is free + + // if collec_one is free + if (!collect_free) { + + // sect collect_one to active + collect_one.active = 1; + + // assign random x/y coordinates within the bounds of the game edges, takes into account the way drawRect works + collect_one.x = rand ()%80 + 1; + collect_one.y = rand ()%44 + 10; + + // draw the collectible + lcd.drawRect(collect_one.x-1,collect_one.y-1,2,2,0); + + }// if collec_two is free + else if (collect_free) { + + // sect collect_one to active + collect_two.active = 1; + + // assign random x/y coordinates within the bounds of the game edges, takes into account the way drawRect works + collect_two.x = rand ()%80 + 1; + collect_two.y = rand ()%44 + 10; + + // draw the collectible + lcd.drawRect(collect_two.x-1,collect_two.y-1,2,2,0); + } + + + +} +// redraw collectible in case it disappeared +void update_collect () +{ + + if (collect_one.active) { + // draw the collectible + lcd.drawRect(collect_one.x-1,collect_one.y-1,2,2,0); + + } + if (collect_two.active) { + // draw the collectible + lcd.drawRect(collect_two.x-1,collect_two.y-1,2,2,0); + } +} + +// check if collectible has been collected +void check_collect () +{ + + // only preform operations if missle is active for efficiency + if (collect_one.active) { + + // ship pointing up + if (ship.direction == UP) { + // check if the collectible is within the ship's the hit box + if ( (collect_one.x > ship.x - 2 ) && (collect_one.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_one.y > ship.y - 2 ) && (collect_one.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + collect_one.active = 0; + // set hit flag for missle 1. + g_collect_flag = 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 1; + } + } + } + // ship pointing down + if (ship.direction == DOWN) { + if ( (collect_one.x > ship.x - 2 ) && (collect_one.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_one.y > ship.y - 3 ) && (collect_one.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + collect_one.active = 0; + // set hit flag for missle 1. + g_collect_flag = 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 1; + } + } + } + // ship pointing left + if (ship.direction == LEFT) { + if ( (collect_one.x > ship.x - 3 ) && (collect_one.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_one.y > ship.y - 2 ) && (collect_one.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + collect_one.active = 0; + // set hit flag for missle 1. + g_collect_flag= 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 1; + } + } + } + // ship pointing right + if (ship.direction == RIGHT) { + if ( (collect_one.x > ship.x - 2 ) && (collect_one.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_one.y > ship.y - 2 ) && (collect_one.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + collect_one.active = 0; + // set hit flag for missle 1. + g_collect_flag = 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 1; + } + } + } + } + + // only preform operations if missle is active for efficiency + if (collect_two.active) { + + // ship pointing up + if (ship.direction == UP) { + // check if the collectible is within the ship's the hit box + if ( (collect_two.x > ship.x - 2 ) && (collect_two.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_two.y > ship.y - 2 ) && (collect_one.y < ship.y + 3) ) { + // set missle to inactive, i.e. missle explodes + collect_two.active = 0; + // set hit flag for missle 1. + g_collect_flag = 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 0; + } + } + } + // ship pointing down + if (ship.direction == DOWN) { + if ( (collect_two.x > ship.x - 2 ) && (collect_two.x < ship.x + 2 ) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_two.y > ship.y - 3 ) && (collect_two.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + collect_two.active = 0; + // set hit flag for missle 1. + g_collect_flag = 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 0; + } + } + } + // ship pointing left + if (ship.direction == LEFT) { + if ( (collect_two.x > ship.x - 3 ) && (collect_two.x < ship.x + 2) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_two.y > ship.y - 2 ) && (collect_two.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + collect_two.active = 0; + // set hit flag for missle 1. + g_collect_flag= 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 0; + } + } + } + // ship pointing right + if (ship.direction == RIGHT) { + if ( (collect_two.x > ship.x - 2 ) && (collect_two.x < ship.x + 3) ) { + // same structure for y-axis of hit box. uses height instead of width + if ( (collect_two.y > ship.y - 2 ) && (collect_two.y < ship.y + 2) ) { + // set missle to inactive, i.e. missle explodes + collect_two.active = 0; + // set hit flag for missle 1. + g_collect_flag = 1; + // since collect_one has been reset, collect_two will expire next + g_what_expired = 0; + } + } + } + + + + } +} +// time left +void time_left () +{ + //with every second decrement time left by 1 + g_time_left --; + + //increases score by 10 every second + g_score = g_score + 10; + + // print timer + char buffer[14]; // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14) + // so can display a string of a maximum 14 characters in length + // or create formatted strings - ensure they aren't more than 14 characters long + int length = sprintf(buffer,"Time: %2d ",g_time_left); // print formatted data to buffer + // it is important the format specifier ensures the length will fit in the buffer + if (length <= 14) // if string will fit on display + lcd.printString(buffer,16,0); // display on screen + +}
diff -r 000000000000 -r 10704407da46 ESP.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ESP.h Thu May 05 10:21:22 2016 +0000 @@ -0,0 +1,319 @@ +/** +@file ESP.h +@brief Header file containing function prototypes, global variables, ticker objects, structs as well as K64F connections +@author Aleksander Filipiak +@date May 2016 +*/ + + +#include "mbed.h" +#include "N5110.h" + + + +/** +@namespace lcd +@brief N5110 library object +@brief pin connections:VCC,SCE,RST,D/C,MOSI,SCLK,LED +*/ +N5110 lcd(PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); + +#define DIRECTION_TOLERANCE 0.05 + +/** +@namespace start_button +@brief GPIO input for "start" button +*/ +DigitalIn start_button(PTE24); + +InterruptIn pause_button(PTE24); +/** +@namespace speed_button +@brief GPIO input for button controlling ship speed +*/ +DigitalIn speed_button(PTE25); +/** +@namespace xPot +@brief GPIO input for joystick's x-axis potentiometer +*/ +AnalogIn xPot(PTB3); +/** +@namespace yPot +@brief GPIO input for joystick's y-axis potentiometer +*/ +AnalogIn yPot(PTB10); + +///creates enumerated type for directions: 0 = UP, 1 = DOWN, 2 = LEFT, 3 = RIGHT, 4 = CENTRE and 6 = UNKNOWN +enum DirectionName { + UP, + DOWN, + LEFT, + RIGHT, + CENTRE, + UNKNOWN +}; + + +typedef struct JoyStick Joystick; +/** +@struct Joystick +@brief Struct for joystick parameters +@param x - current x value +@param x0 - 'centred' x value +@param y - current y value +@param y0 - 'centred' y value +@param direction - direction joystick is set to +@see {DirectionName} +*/ +struct JoyStick { + float x; + float x0; + float y; + float y0; + DirectionName direction; +}; +// create struct variable +Joystick joystick; + +/** flag for joystick update +@see {updateJoystick} +*/ +bool printFlag = 0; + +/** +@struct Ship +@brief Struct for ship parameters +@param x - Current x value of centre pixel +@param y - Current y value of centre pixel +@param direction - Direction of flight +@see {DirectionName} +*/ +typedef struct Ship Ship; +struct Ship { + short x; + short y; + DirectionName direction; +}; +// the ship, controlled by player +Ship ship; + +/** +@struct Turret +@brief Struct for turret parameters +@brief Four turret variables are used: one for each border edge +@param position - Position along relevant axis. Depends on game edge on which the turrent moves long. +@param shoot - Flag raised if missle was fired +@see {shoot} +@param direction - Direction of movement +@see {DirectionName} +*/ +typedef struct Turret Turret; +struct Turret { + short position; + bool shoot; + DirectionName direction; +}; +// four turrets, one for each side +Turret top_turret; +Turret bottom_turret; +Turret left_turret; +Turret right_turret; + +/** +@struct Missle +@brief Struct for missle parameters +@brief Six variables are used, one for each of the six possible acitve missles on the screen +@param x - Position on x-axis +@param y - Position on y-axis +@param direction - Direction of travel +@see {DirectionName} +@param hit_flag - Flag that missle has hit a target +@see {check_hit} +@param active - Is the missle active +@see {shoot} +*/ +typedef struct Missle Missle; +struct Missle { + short x; + short y; + DirectionName direction; + bool hit_flag; + bool active; +}; +// maximum of 6 active missles +Missle missle_one; +Missle missle_two; +Missle missle_three; +Missle missle_four; +Missle missle_five; +Missle missle_six; + +typedef struct Collectible Collectible; +/** +@struct Collectible +@brief Struct for collectible parameters +@brief Two variables are used, one for each possible collectible +@param x - x coordinate of collectible once it appears +@param y - y coordinate of collectible once it appears +@param active - Flag for when the collectible has appeared +@see {print_collect} +*/ +struct Collectible { + short x; + short y; + bool active; +}; +// max number of 6 active collectibles +Collectible collect_one; +Collectible collect_two; + + +// --------------------------------------------------------------------------TICKERS--------------------------------------------------------------------------------------------------- + +/// timer to regularly read the joystick +Ticker pollJoystick; +/// timer for updating missle position +Ticker missle_mover; +/// timer for checking for missle hits +Ticker hit_checker; +/// timer for turrets' shoot function +Ticker shooter; +/// game timer +Ticker timer; +/// timer for updating ship position +Ticker ship_mover; +/// updates position of turrets +Ticker turret_mover; +/// timer for collectible timeout +Ticker collect_timer; +/// triggers function for creating collectibles +Ticker collect_printer; +///Ticker for updating collectible on screen +Ticker collect_updater; +/// triggers function for checking if collectible has been collected +Ticker collect_checker; + +// ---------------------------------------------------------------------------VARIABLES------------------------------------------------------------------------------------------------- + +/** int for keeping track of the number of loops of the change_speed function +@see {speed_change} */ +int g_ship_counter; + +/** variable for time left in game +@see {time_left} */ +int g_time_left; + +/// keep track of score +short g_score; + +/// flag for collectible collected, set in check_collect +volatile bool g_collect_flag; + +/// flag for hit detection +volatile bool g_hit_flag; + +/// flag for collectible timeout, set in collect_timeout(). +volatile bool g_collect_timeout_flag; + +/// variable for storing what collectible (collect_one or collect_two) has expired +volatile bool g_what_expired; + +/// flag for pause function, set in pause_isr +volatile bool g_pause_flag; + + +// ---------------------------------------------------------------------------FUNCTION DECLARATIONS------------------------------------------------------------------------------------- + +/** interrupt for game pause, triggered by pause_button +@see {pause_button} +*/ +void pause_isr(); + +/** read default positions of the joystick to calibrate later readings +@see {Joystick} +*/ +void calibrateJoystick(); + +/** read and update position of the joystick +@see {Joystick} +*/ +void updateJoystick(); + +/** Isr for following timer, decrements g_time_left every second. +@see {g_time_left} +Prints the time left on the above the game borders. +*/ +void timer_isr (); + +/** prints border between four set points +@param x_start - x axis starting point +@param x_end - x axis end point +@param y_start y axis starting point +@param y_end y axis end point +*/ +void print_border (int x_start, int x_end, int y_start, int y_end); + +/** Setup initial screen: prints four turrets and ship in their default positions. +@see {Ship} +@see {Turret}*/ +void setup_game (); + +/** Function for changing the speed of the ship based on the value of speed_button. +@see {speed_button} + Uses a modulus command to either update the ship's position every time the function is called, + i.e. when speed_button is pressed and the ship should fly fast, or only every third time the function is calles, + when the ship should fly at 1/3 of the fast speed. */ +void speed_change(); + + +/** Update ship's position based on joystick controls: clears ship at current position and prints it at the next one. + The shape which is printed depends on the direction of flight set by the joystick controlls. + Stores position and direction of flight in the Ship struct. limits flight of ship to within the game boders + Is contained withing the speed_change function. +@see {change_speed} +@see {Ship}*/ +void update_ship (); + +/** Updates the position of the four turrets, clears turrets at current position and prints them at their new positions. + Turrets move along their respective axis until they hit the game screen boundry, then they travel in the opposite direction. + function is triggered at regular intervals by turret_mover Ticker. +@see {Turret} */ +void update_turrets(); + +/** At regular intervals, dictated by shoort Ticker, gives each turret a 50% chance to shoot a missle. + Turret will shoot if any of the 6 possible missles are available. If a missle is available, its starting x/y position and direction of flight + will be set to that of the middle of the turret, and it will be set to active.*/ +void shoot(); + +/** updates the position of all active missles at regular intervals. +@see {missle_mover} +@see {shoot} + */ +void update_missles (); + +/** Checks if missle has hit the ship, triggered by hit_checker Ticker. + Works by checking if the central pixel of the active missle has is inside the ship's "hit-box": a rectangle around its dimensions. + hit-box implementation idea sourced from: +@see {https://www.youtube.com/watch?v=POVQBI9icDs} +@brief also deactivates and clears missles when the reach the game border +@see {update_missles}*/ +void check_hit(); + +/** Checks if ship has moved through collectible by checking if the centre of the collectible is within the bounds of the ship's hit box. +@see {check_hit}*/ +void check_collect (); + +/** every 10 seconds the function sets a flag signaling that the oldest collectible has expired +@see {print_collect}*/ +void collect_timeout(); + +/** re-draws the collectible in case another object has removed it off the screen*/ +void update_collect(); + +/** prints a collectible at random x/y coordinates every 5 seconds. Up to two collectibles can exist at a time. If two collectibles exist already +the finction will alternate between which one expires when the collec_timeout_flag is set. +@see {collect_timeout}*/ +void print_collect(); + +/** decrements the timer every second and prints the time left above the game borders*/ +void time_left(); \ No newline at end of file
diff -r 000000000000 -r 10704407da46 N5110.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/N5110.lib Thu May 05 10:21:22 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/eencae/code/N5110/#ba8addc061ea
diff -r 000000000000 -r 10704407da46 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu May 05 10:21:22 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/87f2f5183dfb \ No newline at end of file