Lab1

Dependencies:   mbed C12832

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