
Lab1
Diff: KF_20901830_space_invaders.cpp
- Revision:
- 10:2fabc22afe95
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/KF_20901830_space_invaders.cpp Mon Nov 23 11:30:36 2020 +0000 @@ -0,0 +1,297 @@ +/* +* Konstantinos Fane +* kf289@kent.ac.uk +* ID: 20901830 +*/ + +#include "mbed.h" +#include "C12832.h" // LCD display +#include "graphics.h" + +int numsprite; +int setup_shooter(); +int draw_shooter(int, int); //Display the shooter at some point shx +int getnew_shooter(int); // get the new shooter position (X axis) +void draw_sprite(struct sprite *); +void endgame(char); +Bitmap bm ; //Create a bitmap structure + +//custom implemented functions and variables +void move_sprite(); +void draw_moving_bullet(int, int); +void kill_sprite(struct sprite *); +int bullet_x_pos; +int killed_sprites = 0; +Timer m_t; //to be used for the interrupts that trigger the downward movement + + +int main() +{ + + m_t.start(); //initialise the "move_down" timer + + int nsxp; // new shooter x position + int osxp; // old shooter x position + + //Set up the bitmap parameters for the display objects + bm.xSize = 16; // 16 pixels wide + bm.ySize = 8; // 8 pixels high + bm.Byte_in_Line = 2; //i.e. 16bits + + //Initialise the PWM period for the multi colour LED control + r.period(0.001); + //And turn the 2 active (R and G) colours off + r = 1.0; g = 1.0; + + // Draw the shooter image in its initial position + // i.e x = 1 and y = 24 the base line + osxp = setup_shooter(); + + move_sprite(); + + while(1) + { + // Get the new shooter position + nsxp = getnew_shooter(osxp); + + //And draw it + osxp = draw_shooter(nsxp,osxp); + wait(0.02); + + if(m_t.read() > 2) //wait for 2 teconds to create interrupt + { + move_sprite(); + m_t.reset(); + } + + //doesnt matter which spritetab entry is cheched, as even if its killed, + //its position will still be incremented + if(spritetab[0].ypos >= 18) + { + endgame(LOSE); + break; //while is terminated here + } + + //checks whether all sprites have been killed + if(killed_sprites == 8) + { + endgame(WIN); + break; + } + + if(joyC) + { + //Assign the position of the bullet shooting point to be the same as the tip of the shooter + bullet_x_pos = nsxp + 5; + draw_moving_bullet(bullet_x_pos, BASE); + + //destroys the allien sprint + if(bullet_x_pos >=1 && bullet_x_pos <=10) + { + //checks if the sprint has been destroyed already + if(spritetab[0].active == 1) + { + spritetab[0].active = 0; + kill_sprite(&spritetab[0]); + killed_sprites++; //counter to keep track of how many sprites are killed, to determine whether the game has been won + } + } + + if(bullet_x_pos >=16 && bullet_x_pos <=26) + { + if(spritetab[1].active == 1) + { + spritetab[1].active = 0; + kill_sprite(&spritetab[1]); + killed_sprites++; + } + } + + if(bullet_x_pos >=32 && bullet_x_pos <=42) { + if(spritetab[2].active == 1) + { + spritetab[2].active = 0; + kill_sprite(&spritetab[2]); + killed_sprites++; + } + } + + if(bullet_x_pos >=48 && bullet_x_pos <=58) { + if(spritetab[3].active == 1) + { + spritetab[3].active = 0; + kill_sprite(&spritetab[3]); + killed_sprites++; + } + } + + if(bullet_x_pos >=64 && bullet_x_pos <=74) { + if(spritetab[4].active == 1) + { + spritetab[4].active = 0; + kill_sprite(&spritetab[4]); + killed_sprites++; + } + } + + if(bullet_x_pos >=80 && bullet_x_pos <=90) { + if(spritetab[5].active == 1) + { + spritetab[5].active = 0; + kill_sprite(&spritetab[5]); + killed_sprites++; + } + } + + if(bullet_x_pos >=96 && bullet_x_pos <=106) { + if(spritetab[6].active == 1) + { + spritetab[6].active = 0; + kill_sprite(&spritetab[6]); + killed_sprites++; + } + } + + if(bullet_x_pos >=112 && bullet_x_pos <=123) { + if(spritetab[7].active == 1) + { + spritetab[7].active = 0; + kill_sprite(&spritetab[7]); + killed_sprites++; + } + } + } + + } + + return 0; + } + + //function to print th travelling bullet +void draw_moving_bullet(int bxpos, int bypos) +{ + lcd.setmode(XOR); //similar to how draw_sprite works + for( int j=bypos; j>=0; j--) { + lcd.pixel(bxpos, j, 1); + lcd.pixel(bxpos, j-1, 1); + lcd.pixel(bxpos, j-2, 1); + lcd.pixel(bxpos, j-3, 1); + wait(0.02); //wait is introduced so that the bullet is visible in the screen + lcd.copy_to_lcd(); //only one is used, because if a second was used it would delete the bullet drawn already due to the XOR + lcd.pixel(bxpos, j, 1); + lcd.pixel(bxpos, j-1, 1); + lcd.pixel(bxpos, j-2, 1); + lcd.pixel(bxpos, j-3, 1); + } +} + +//implementation of sprite kill, is parsed the value of the spritetab[i] +void kill_sprite(struct sprite *ps) +{ + //a second print of the same object at the same position deletes the + //object @ spritetab[i] + bm.data = ps->type; //assigning the type of the spritetab[i] to the bitmap variable + lcd.print_bm(bm, ps->xpos, ps->ypos); //prints the created bitmap at the corresponding x,y positions copies the printed data to lcd +} + + +void move_sprite() +{ + for (numsprite = 0; numsprite <= 7; numsprite++) { + + spritetab[numsprite].oldy = spritetab[numsprite].ypos; + spritetab[numsprite].ypos++; + + //in here it checks to see whether the sprite is active or not, + //if yes it prints it, if not it doesnt print it + if(spritetab[numsprite].active != 0) + { + draw_sprite(&spritetab[numsprite]); + } + } +} + +// setup the shooter image at location 1 +int setup_shooter() +{ + lcd.cls(); //Clear the screen + return (draw_shooter(1,0)); +} + + +// Display the shooter at location shx the Y location (BASE) is always 24 +int draw_shooter(int shx, int oldx)//shx = new position , oldx = current (old) position +{ + bm.data = shooter; // use the shooter image + lcd.setmode(XOR); // XOR mode a second write in the same place erases the image + + if (oldx != 0) { + //first time round + lcd.print_bm(bm, oldx, BASE); // so this erases current shooter + lcd.copy_to_lcd(); + } + + lcd.print_bm(bm, shx, BASE); // and this draws the new shooter at location shx + lcd.copy_to_lcd(); // update lcd + return shx; // 'current' position returned to become 'old' position + +} + +/* Get the new shooter X position in response to left or right +joystick movements stops at limits x = 1 and x = 112 */ +int getnew_shooter(int oldx) +{ + int tmpx = oldx; + if (joyL) tmpx--; + if (tmpx <= 1) tmpx = 1; + if (joyR) tmpx++; + if (tmpx >= 112) tmpx = 112; + return tmpx; +} + + // Determine sprite 1 or 2 and display + void draw_sprite(struct sprite *ps) + { + + bm.data = ps->type; // use sprite image as defined by type + lcd.setmode(XOR); // XOR mode a second write in the same place erases the image + + if (ps->oldy != 0){ // first time round + lcd.print_bm(bm, ps->xpos, ps->oldy); // so this erases current sprite + lcd.copy_to_lcd(); + } + + lcd.print_bm(bm, ps->xpos, ps->ypos); // and this draws the new sprite at location + lcd.copy_to_lcd(); // update lcd + } + +void endgame( char result) // LED == GREEN for WIN +{ + if(result == WIN) + { + lcd.cls(); + lcd.locate(20,12); + lcd.printf("*** YOU WON ***"); + + r = 1.0; + g = 0.0; + } + else + { + lcd.cls(); + lcd.locate(17,12); + lcd.printf("*** GAME OVER ***"); + + r = 0.0; + g = 1.0; + } + + wait(2); + lcd.cls(); + lcd.locate(13,1); + lcd.printf("This game was made by"); + lcd.locate(24,11); + lcd.printf("Konstantinos Fane"); + lcd.locate(25,21); + lcd.printf("kf289@kent.ac.uk"); +} \ No newline at end of file