Space Invaders - Embedded Systems Project 15/16 - Avinash Patel 200860407

Dependencies:   Joystick N5110 SDFileSystem mbed

Revision:
2:d34c95990605
Parent:
1:b300d052d549
Child:
3:544b59d60ab8
--- a/main.cpp	Sun Mar 13 17:03:33 2016 +0000
+++ b/main.cpp	Sun Mar 27 17:30:13 2016 +0000
@@ -4,11 +4,24 @@
 Week 19 - Set up joystick class
 Week 20 - Changed to space invaders as constrained too much by screen resolution
         - Core cannon is drawn and can move, enemies are visible and they switch between states every second
+Week 21 - Begun to set up barriers
 */
 #include "mbed.h"
 #include "N5110.h"
 
+//Direction invaders are travelling
+#define LEFT 0
+#define RIGHT 1
+
+//Preprocessor for screen map
 #define EMPTY 0
+#define CANNON 1
+#define SMALL 2
+#define MEDIUM 3
+#define LARGE 4
+#define BARRIER 5
+#define UFO 6
+#define CANNON_SHOT 7
 
 //Joystick Class
 class Joystick
@@ -25,16 +38,12 @@
     //Sets up the ISRs and grabs the offsets for each axis
     void init() {
         //Sets up the button ISR
-        //DigitalOut* b = new DigitalOut(LED_BLUE);
-
         button_->mode(PullUp);
-        //read_ticker_->attach(this, &Joystick::read_ticker_isr, time); //Samples joystick every second
         button_->fall(this, &Joystick::button_isr);
 
         //Initalises the vairables and flags
         x_offset_ = 0;
         y_offset_ = 0;
-        g_read_flag_ = 0;
         g_button_flag_ = 0;
 
         //Samples the joystick 5 times and takes an average to get the offset
@@ -91,23 +100,7 @@
         }
     }
 
-    float ReadXAxis() {
-        return x_axis_->read();
-    }
-
-    float ReadYAxis() {
-        return y_axis_->read();
-    }
-
     //Getter and setters for flags
-    int get_read_flag() {
-        return g_read_flag_;
-    }
-
-    void set_read_flag(int value) {
-        g_read_flag_ = value;
-    }
-
     int get_button_flag() {
         return g_button_flag_;
     }
@@ -116,11 +109,6 @@
         g_button_flag_ = value;
     }
 
-    //Ticker ISR Method
-    void read_ticker_isr() {
-        g_read_flag_ = 1;
-    }
-
 private:
     //Button ISR Method
     void button_isr() {
@@ -133,15 +121,11 @@
     AnalogIn* y_axis_;
     InterruptIn* button_;
 
-    //Ticker
-    Ticker* read_ticker_;
-
     //Stores X and Y offsets
     float x_offset_;
     float y_offset_;
 
     //Stores interrupt flags
-    volatile int g_read_flag_;
     volatile int g_button_flag_;
 };
 
@@ -158,11 +142,18 @@
 Serial pc(USBTX,USBRX);
 
 //Joystick
-Joystick joystick(PTC10, PTC11, PTB11);
+Joystick joystick(PTB2, PTB3, PTB11);
+
+//Shoot button
+InterruptIn shoot_button(PTB18);
 
 //LCD object
 //         VCC,    SCE,   RST,   D/C,   MOSI,  SCLK,   LED
 N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
+Ticker update_screen;
+
+//Map holding pixel data of screen
+short screen_map[84][48];
 
 //Ship bit-map and location
 int cannon_xpos = 24;
@@ -176,19 +167,29 @@
     {1, 1, 1, 1, 1, 1, 1, 1, 1}
 };
 
+Ticker move_cannon_shot;
+bool cannon_shot_on_screen = false;
+int cannon_shot_x_pos = 28;
+int cannon_shot_y_pos = 40;
+bool game_over = false;
+
 //Enemies
 Ticker move_enemies;
-short screen[84][48];
-bool enemies_in_state2 = true;
+bool invaders_in_state2 = true;
+bool invader_direction = RIGHT;
 //Struct to store enemy data
-struct Enemies {
+struct Invaders {
     int x_pos;
     int y_pos;
     bool is_alive;
-} small_invader[6], medium_invader[6], large_invader[6];
-int no_of_small_invaders = 6;
-int no_of_medium_invaders = 6;
-int no_of_large_invaders = 6;
+} small_invader[5], medium_invader[5], large_invader[5];
+int right_column_alive = 4;
+int left_column_alive = 0;
+enum LowestInvaderRow {small, medium, large};
+LowestInvaderRow lowest_invader_row_alive = large;
+//Limits the first invader can travel
+int minimum_invader_x_pos = 0;
+int maximum_invader_x_pos = 20;
 //Bitmaps for small invaders
 const bool small_invader_bitmap_1[6][8] = {
     {0, 0, 0, 1, 1, 0, 0, 0},
@@ -227,7 +228,7 @@
 };
 //Bitmaps for large invaders
 const bool large_invader_bitmap_1[6][12] = {
-    {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
+    {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0},
     {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
     {1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1},
     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
@@ -236,7 +237,7 @@
 };
 
 const bool large_invader_bitmap_2[6][12] = {
-    {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
+    {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0},
     {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
     {1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1},
     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
@@ -244,11 +245,42 @@
     {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}
 };
 
-//int row_no = 6;
-//int col_no = 12;
+//Barriers
+struct Barriers {
+    int x_pos;
+    int y_pos;
+    bool before_bitmap[8][14];
+    bool after_bitmap[8][14];
+} barrier[3];
+int no_of_barriers = 3;
+const bool barrier_bitmap[8][14] = {
+    {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
+    {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},
+    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+    {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1},
+    {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
+    {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+    {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1}
+};
+
+//TEST FOR SPEC UFO
+const bool ufo_bitmap[5][14] = {
+    {0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+    {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},
+    {0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0},
+    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+    {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}
+};
+
+int row_no = 5;
+int col_no = 14;
 
 //ISR Flags
-volatile bool g_move_ship_flag = true;
+volatile bool g_update_screen_flag = true;
+volatile bool g_move_cannon_flag = true;
+volatile bool g_shoot_pressed_flag = false;
+volatile bool g_move_cannon_shot_flag = false;
 volatile bool g_move_enemies_flag = true;
 
 // function prototypes
@@ -258,82 +290,197 @@
 void init_serial();
 // set-up the on-board LEDs and switches
 void init_K64F();
+//Init shoot button
+void init_shoot();
 // Added functions
-void MoveShip();
+void MoveCannon();
 void InitSmallInvaders();
+void ClearSmallInvaders();
 void DrawSmallInvaders();
+void ClearMediumInvaders();
 void InitMediumInvaders();
 void DrawMediumInvaders();
 void InitLargeInvaders();
+void CLearLargeInvaders();
 void DrawLargeInvaders();
+void InitBarriers();
+void DrawBarriers();
+void ShiftInvaderXPositions();
+void ShiftInvaderYPositions(bool new_direction);
+//void InitUFO();
+void DrawUFO();
+//void DrawEnemies(struct Invaders invader[], int no_of_invaders);
+
 //ISR's
-void move_ship_isr();
+void update_screen_isr();
+void move_cannon_isr();
 void move_enemies_isr();
+void shoot_pressed_isr();
+void move_cannon_shot_isr();
 
-
+int down_count = 0;
 
 int main()
 {
     //Initalises the board and perhiperals
     init_K64F();
     init_serial();
+    init_shoot();
     lcd.init();
     lcd.clear();
 
-    move_cannon.attach(&move_ship_isr, 0.1);
+    update_screen.attach(&update_screen_isr, 0.05);
+    move_cannon.attach(&move_cannon_isr, 0.05);
     move_enemies.attach(&move_enemies_isr, 1);
 
     InitSmallInvaders();
     InitMediumInvaders();
     InitLargeInvaders();
+    InitBarriers();
 
-    int col = 0;
-    int row = 0;
+    lcd.refresh();
+
+    while (true) {
+        //IF the game is over detach all the tickers
+        if (game_over) {
+            move_cannon.detach();
+            move_enemies.detach();
 
-    for (int i = 0; i < no_of_large_invaders; i++) {
-        if (i == 0) {
-            for (col = 0; col < 12; col++) {
-                for (row = 0; row < 6; row++) {
-                    if(large_invader_bitmap_1[row][col]) {
-                        lcd.setPixel(large_invader[i].x_pos + col, large_invader[i].y_pos + row);
+            lcd.clear();
+            lcd.printString("Game Over", 1, 2);
+        } else {
+            //Updates pixels on the screen
+            if (g_update_screen_flag) {
+                g_update_screen_flag = false;
+
+                //Loops through the screen map and sets pixels on the LCD
+                for (int col = 0; col < 84; col++) {
+                    for (int row = 0; row < 48; row++) {
+                        if (screen_map[col][row]) {
+                            lcd.setPixel(col, row);
+                        } else {
+                            lcd.clearPixel(col, row);
+                        }
                     }
                 }
             }
-        } else {
-            for (col = 0; col < 12; col++) {
-                for (row = 0; row < 6; row++) {
-                    if(large_invader_bitmap_2[row][col]) {
-                        lcd.setPixel(large_invader[i].x_pos + col, large_invader[i].y_pos + row);
+            //Controls cannon movement
+            if (g_move_cannon_flag) {
+                g_move_cannon_flag = false;
+
+                MoveCannon();
+                DrawBarriers();
+
+                lcd.refresh();
+            }
+            //Spawns a player bullet if the shoot button is pressed and there isn't a bullet on the screen
+            if (g_shoot_pressed_flag) {
+                g_shoot_pressed_flag = false;
+
+                pc.printf("Shot Fired\n");
+
+                //Add 4 to cannon x_pos to get shot x_pos
+                cannon_shot_x_pos = cannon_xpos + 4;
+                cannon_shot_y_pos = 40;
+                cannon_shot_on_screen = true;
+                move_cannon_shot.attach(&move_cannon_shot_isr, 0.1);
+            }
+            //Move the cannon's shot
+            if (g_move_cannon_shot_flag) {
+                g_move_cannon_shot_flag = false;
+
+                //Checks bullet will not go beyond the bounds of the screen map
+                if (cannon_shot_y_pos > -1) {
+                    //Loops throught the shot bitmap and sets the pixels in the screen map
+                    for (int row = 0; row < 3; row++) {
+                        //Clears the position where the bullet was
+                        screen_map[cannon_shot_x_pos][cannon_shot_y_pos + row] = EMPTY;
+                    }
+
+                    //Increments the shot going up the screen
+                    cannon_shot_y_pos--;
+
+                    for (int row = 0; row < 3; row++) {
+                        switch (screen_map[cannon_shot_x_pos][cannon_shot_y_pos + row]) {
+                            case SMALL:
+                                pc.printf("Small Hit\n");
+                                cannon_shot_on_screen = false;
+                                move_cannon_shot.detach();
+                                break;
+                            case MEDIUM:
+                                pc.printf("Medium Hit\n");
+                                cannon_shot_on_screen = false;
+                                move_cannon_shot.detach();
+                                break;
+                            case LARGE:
+                                pc.printf("Large Hit\n");
+                                cannon_shot_on_screen = false;
+                                move_cannon_shot.detach();
+                                break;
+                            case BARRIER:
+                                pc.printf("Barrier Hit\n");
+                                cannon_shot_on_screen = false;
+                                move_cannon_shot.detach();
+                                break;
+                            case UFO:
+                                pc.printf("UFO Hit\n");
+                                cannon_shot_on_screen = false;
+                                move_cannon_shot.detach();
+                                break;
+                            default:
+                                screen_map[cannon_shot_x_pos][cannon_shot_y_pos + row] = CANNON_SHOT;
+                        }
                     }
                 }
             }
         }
-    }
-
-    lcd.refresh();
-
-    while (true) {
-        
-        if (g_move_ship_flag) {
-            g_move_ship_flag = false;
-
-            MoveShip();
-
-            lcd.refresh();
-        }
-
+        //Controls enemy movement
         if (g_move_enemies_flag) {
             g_move_enemies_flag = false;
 
+            //Added stuff to move to function
+            //Checks which columns of invaders are alive on the right and left sides and changes the limits of the first invader
+            //MOVE TO COLLISION DETECTION WHEN IT'S DONE
+            //Checking the left side
+            for (int i = 0; i < 5; i++) {
+                if (small_invader[i].is_alive || medium_invader[i].is_alive || large_invader[i].is_alive) {
+                    left_column_alive = i;
+                    break;
+                }
+            }
+            minimum_invader_x_pos = 0 - left_column_alive*13;
+            //Checking the right side
+            for (int j = 4; j >= 0; j--) {
+                if (small_invader[j].is_alive || medium_invader[j].is_alive || large_invader[j].is_alive) {
+                    right_column_alive = j;
+                    break;
+                }
+            }
+            maximum_invader_x_pos = 72 - right_column_alive*13;
+
+            //End of block
+
+            //Clears the old bitmaps
+            ClearSmallInvaders();
+            ClearMediumInvaders();
+            CLearLargeInvaders();
+
+            ShiftInvaderXPositions();
+
             DrawSmallInvaders();
             DrawMediumInvaders();
             DrawLargeInvaders();
+            DrawUFO();
 
-            enemies_in_state2 = !enemies_in_state2;
+            invaders_in_state2 = !invaders_in_state2;
 
             lcd.refresh();
+
+            //TEST CODE
+
+            //END
         }
-        
+
         sleep();
     }
 }
@@ -368,18 +515,41 @@
     pc.baud(115200);
 }
 
-void move_ship_isr()
+void init_shoot()
 {
-    g_move_ship_flag = true;
+    shoot_button.mode(PullUp);
+    shoot_button.fall(&shoot_pressed_isr);
+
+}
+
+void update_screen_isr()
+{
+    g_update_screen_flag = true;
 }
 
-void MoveShip()
+void shoot_pressed_isr()
+{
+    g_shoot_pressed_flag = true;
+}
+
+void move_cannon_shot_isr()
+{
+    g_move_cannon_shot_flag = true;
+}
+
+void move_cannon_isr()
+{
+    g_move_cannon_flag = true;
+}
+
+void MoveCannon()
 {
     //Clears the ship
     for (int col = 0; col < 9; col++) {
         for (int row = 0; row < 5; row++) {
             if(cannon_bitmap[row][col]) {
-                lcd.clearPixel(cannon_xpos+col, cannon_ypos+row);
+                //lcd.clearPixel(cannon_xpos+col, cannon_ypos+row);
+                screen_map[cannon_xpos+col][cannon_ypos+row] = EMPTY;
             }
         }
     }
@@ -401,7 +571,8 @@
     for (int col = 0; col < 9; col++) {
         for (int row = 0; row < 5; row++) {
             if(cannon_bitmap[row][col]) {
-                lcd.setPixel(cannon_xpos+col, cannon_ypos+row);
+                //lcd.setPixel(cannon_xpos+col, cannon_ypos+row);
+                screen_map[cannon_xpos+col][cannon_ypos+row] = CANNON;
             }
         }
     }
@@ -415,39 +586,60 @@
 //Sets the position and aliveness of the small invaders
 void InitSmallInvaders()
 {
-    for (int i = 0; i < no_of_small_invaders; i++) {
+    for (int i = 0; i < 5; i++) {
         small_invader[i].x_pos = 2+ (i*13);
-        small_invader[i].y_pos = 7;
+        small_invader[i].y_pos = 1;
         small_invader[i].is_alive = true;
     }
 }
 
+void ClearSmallInvaders()
+{
+    for (int i = 0; i < 5; i++) {
+        if (!invaders_in_state2) {
+            for (int col = 0; col < 8; col++) {
+                for (int row = 0; row < 6; row++) {
+                    if(small_invader_bitmap_1[row][col]) {
+                        //lcd.clearPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
+                        screen_map[small_invader[i].x_pos + col][small_invader[i].y_pos + row] = EMPTY;
+                    }
+                }
+            }
+        } else {
+            for (int col = 0; col < 8; col++) {
+                for (int row = 0; row < 6; row++) {
+                    if(small_invader_bitmap_2[row][col]) {
+                        //lcd.clearPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
+                        screen_map[small_invader[i].x_pos + col][small_invader[i].y_pos + row] = EMPTY;
+                    }
+                }
+            }
+        }
+    }
+}
+
 void DrawSmallInvaders()
 {
     //For each small invader clear and redraws them if they're alive
-    for (int i = 0; i < no_of_small_invaders; i++) {
-        //Clears the enemy position
-        lcd.drawRect(small_invader[i].x_pos, small_invader[i].y_pos, 8, 6, 2);
-
+    for (int i = 0; i < 5; i++) {
         //Checks if the invader is alive
         if (small_invader[i].is_alive) {
             //Reads off the bitmap and sets the allowed pixels
-            int col = 0;
-            int row = 0;
-            //Flips the bitmap everytime the function is called
-            if (enemies_in_state2) {
-                for (col = 0; col < 8; col++) {
-                    for (row = 0; row < 6; row++) {
+            if (invaders_in_state2) {
+                for (int col = 0; col < 8; col++) {
+                    for (int row = 0; row < 6; row++) {
                         if(small_invader_bitmap_1[row][col]) {
-                            lcd.setPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
+                            //lcd.setPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
+                            screen_map[small_invader[i].x_pos + col][small_invader[i].y_pos + row] = SMALL;
                         }
                     }
                 }
             } else {
-                for (col = 0; col < 8; col++) {
-                    for (row = 0; row < 6; row++) {
+                for (int col = 0; col < 8; col++) {
+                    for (int row = 0; row < 6; row++) {
                         if(small_invader_bitmap_2[row][col]) {
-                            lcd.setPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
+                            //lcd.setPixel(small_invader[i].x_pos + col, small_invader[i].y_pos + row);
+                            screen_map[small_invader[i].x_pos + col][small_invader[i].y_pos + row] = SMALL;
                         }
                     }
                 }
@@ -459,39 +651,60 @@
 //Sets the position and aliveness of the medium invaders
 void InitMediumInvaders()
 {
-    for (int i = 0; i < no_of_medium_invaders; i++) {
+    for (int i = 0; i < 5; i++) {
         medium_invader[i].x_pos = 1 + (i*13);
-        medium_invader[i].y_pos = 15;
+        medium_invader[i].y_pos = 8;
         medium_invader[i].is_alive = true;
     }
 }
 
+void ClearMediumInvaders()
+{
+    for (int i = 0; i < 5; i++) {
+        if (!invaders_in_state2) {
+            for (int col = 0; col < 10; col++) {
+                for (int row = 0; row < 6; row++) {
+                    if(medium_invader_bitmap_1[row][col]) {
+                        //lcd.clearPixel(medium_invader[i].x_pos + col, medium_invader[i].y_pos + row);
+                        screen_map[medium_invader[i].x_pos + col][medium_invader[i].y_pos + row] = EMPTY;
+                    }
+                }
+            }
+        } else {
+            for (int col = 0; col < 10; col++) {
+                for (int row = 0; row < 6; row++) {
+                    if(medium_invader_bitmap_2[row][col]) {
+                        //lcd.clearPixel(medium_invader[i].x_pos + col, medium_invader[i].y_pos + row);
+                        screen_map[medium_invader[i].x_pos + col][medium_invader[i].y_pos + row] = EMPTY;
+                    }
+                }
+            }
+        }
+    }
+}
+
 void DrawMediumInvaders()
 {
     //For each small invader clear and redraws them if they're alive
-    for (int i = 0; i < no_of_medium_invaders; i++) {
-        //Clears the enemy position
-        lcd.drawRect(medium_invader[i].x_pos, medium_invader[i].y_pos, 10, 6, 2);
-
+    for (int i = 0; i < 5; i++) {
         //Checks if the invader is alive
         if (medium_invader[i].is_alive) {
             //Reads off the bitmap and sets the allowed pixels
-            int col = 0;
-            int row = 0;
-            //Flips the bitmap everytime the function is called
-            if (enemies_in_state2) {
-                for (col = 0; col < 10; col++) {
-                    for (row = 0; row < 6; row++) {
+            if (invaders_in_state2) {
+                for (int col = 0; col < 10; col++) {
+                    for (int row = 0; row < 6; row++) {
                         if(medium_invader_bitmap_1[row][col]) {
-                            lcd.setPixel(medium_invader[i].x_pos + col, medium_invader[i].y_pos + row);
+                            //lcd.setPixel(medium_invader[i].x_pos + col, medium_invader[i].y_pos + row);
+                            screen_map[medium_invader[i].x_pos + col][medium_invader[i].y_pos + row] = MEDIUM;
                         }
                     }
                 }
             } else {
-                for (col = 0; col < 10; col++) {
-                    for (row = 0; row < 6; row++) {
+                for (int col = 0; col < 10; col++) {
+                    for (int row = 0; row < 6; row++) {
                         if(medium_invader_bitmap_2[row][col]) {
-                            lcd.setPixel(medium_invader[i].x_pos + col, medium_invader[i].y_pos + row);
+                            //lcd.setPixel(medium_invader[i].x_pos + col, medium_invader[i].y_pos + row);
+                            screen_map[medium_invader[i].x_pos + col][medium_invader[i].y_pos + row] = MEDIUM;
                         }
                     }
                 }
@@ -503,27 +716,83 @@
 //Sets the position and aliveness of the large invaders
 void InitLargeInvaders()
 {
-    for (int i = 0; i < no_of_large_invaders; i++) {
+    for (int i = 0; i < 5; i++) {
         large_invader[i].x_pos = 0 + (i*13);
-        large_invader[i].y_pos = 23;
+        large_invader[i].y_pos = 15;
         large_invader[i].is_alive = true;
     }
 }
 
+void CLearLargeInvaders()
+{
+    for (int i = 0; i < 5; i++) {
+        //Reads off the bitmap and sets the allowed pixels
+        if (!invaders_in_state2) {
+            for (int col = 0; col < 12; col++) {
+                for (int row = 0; row < 6; row++) {
+                    if(large_invader_bitmap_1[row][col]) {
+                        ///lcd.clearPixel(large_invader[i].x_pos + col, large_invader[i].y_pos + row);
+                        screen_map[large_invader[i].x_pos + col][large_invader[i].y_pos + row] = EMPTY;
+                    }
+                }
+            }
+        } else {
+            for (int col = 0; col < 12; col++) {
+                for (int row = 0; row < 6; row++) {
+                    if(large_invader_bitmap_2[row][col]) {
+                        //lcd.clearPixel(large_invader[i].x_pos + col, large_invader[i].y_pos + row);
+                        screen_map[large_invader[i].x_pos + col][large_invader[i].y_pos + row] = EMPTY;
+                    }
+                }
+            }
+        }
+    }
+}
+
 void DrawLargeInvaders()
 {
     //For each small invader clear and redraws them if they're alive
-    for (int i = 0; i < no_of_large_invaders; i++) {
+    for (int i = 0; i < 5; i++) {
+        //Checks if the invader is alive
+        if (large_invader[i].is_alive) {
+            //Reads off the bitmap and sets the allowed pixels
+            if (invaders_in_state2) {
+                for (int col = 0; col < 12; col++) {
+                    for (int row = 0; row < 6; row++) {
+                        if(large_invader_bitmap_1[row][col]) {
+                            //lcd.setPixel(large_invader[i].x_pos + col, large_invader[i].y_pos + row);
+                            screen_map[large_invader[i].x_pos + col][large_invader[i].y_pos + row] = LARGE;
+                        }
+                    }
+                }
+            } else {
+                for (int col = 0; col < 12; col++) {
+                    for (int row = 0; row < 6; row++) {
+                        if(large_invader_bitmap_2[row][col]) {
+                            //lcd.setPixel(large_invader[i].x_pos + col, large_invader[i].y_pos + row);
+                            screen_map[large_invader[i].x_pos + col][large_invader[i].y_pos + row] = LARGE;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+/*
+void DrawInvaders(struct Invaders invader[], int no_of_invaders, bool bitmap[][])
+{
+    //For each small invader clear and redraws them if they're alive
+    for (int i = 0; i < no_of_invaders; i++) {
         //Clears the enemy position
-        lcd.drawRect(large_invader[i].x_pos, large_invader[i].y_pos, 12, 6, 2);
+        lcd.drawRect(invader[i].x_pos, invader[i].y_pos, 12, 6, 2);
 
         //Checks if the invader is alive
-        if (large_invader[i].is_alive) {
+        if (invader[i].is_alive) {
             //Reads off the bitmap and sets the allowed pixels
             int col = 0;
             int row = 0;
             //Flips the bitmap everytime the function is called
-            if (enemies_in_state2) {
+            if (invaders_in_state2) {
                 for (col = 0; col < 12; col++) {
                     for (row = 0; row < 6; row++) {
                         if(large_invader_bitmap_1[row][col]) {
@@ -542,4 +811,113 @@
             }
         }
     }
+}
+*/
+
+
+void InitBarriers()
+{
+    for (int i = 0; i < no_of_barriers; i++) {
+        barrier[i].x_pos = 10 + (i*25);
+        barrier[i].y_pos = 33;
+        //Copies the bitmap into the structs
+        memcpy(barrier[i].before_bitmap, barrier_bitmap, sizeof(barrier_bitmap));
+        memcpy(barrier[i].after_bitmap, barrier_bitmap, sizeof(barrier_bitmap));
+    }
+}
+
+void DrawBarriers()
+{
+    //Clears the barrier and redraws it with damage applied
+    for (int i = 0; i < no_of_barriers; i++) {
+        for (int col = 0; col < 14; col++) {
+            for (int row = 0; row < 8; row++) {
+                if (barrier[i].before_bitmap[row][col]) {
+                    //lcd.clearPixel(barrier[i].x_pos + col, barrier[i].y_pos + row);
+                    screen_map[barrier[i].x_pos + col][barrier[i].y_pos + row] = EMPTY;
+                }
+                if (barrier[i].after_bitmap[row][col]) {
+                    //lcd.setPixel(barrier[i].x_pos + col, barrier[i].y_pos + row);
+                    screen_map[barrier[i].x_pos + col][barrier[i].y_pos + row] = BARRIER;
+                }
+            }
+        }
+        //Copies the after array to the before array
+        memcpy(barrier[i].before_bitmap, barrier[i].after_bitmap, sizeof(barrier[i].after_bitmap));
+    }
+}
+
+void ShiftInvaderXPositions()
+{
+    if (invader_direction == RIGHT) {
+        //Checks the first large invader to see if it can travel anymore
+        if (large_invader[0].x_pos < maximum_invader_x_pos) {
+            for (int i = 0; i < 5; i++) {
+                small_invader[i].x_pos += 2;
+                medium_invader[i].x_pos += 2;
+                large_invader[i].x_pos += 2;
+            }
+        } else {
+            ShiftInvaderYPositions(LEFT);
+        }
+    } else {
+        //Checks the first large invader to see if it can travel anymore
+        if (large_invader[0].x_pos > minimum_invader_x_pos) {
+            for (int i = 0; i < 5; i++) {
+                small_invader[i].x_pos -= 2;
+                medium_invader[i].x_pos -= 2;
+                large_invader[i].x_pos -= 2;
+            }
+        } else {
+            ShiftInvaderYPositions(RIGHT);
+        }
+    }
+}
+
+void ShiftInvaderYPositions(bool new_direction)
+{
+    //Checks to see which row of invaders are still alive to work out maximum y positions
+    if (large_invader[0].is_alive || large_invader[1].is_alive || large_invader[2].is_alive || large_invader[3].is_alive || large_invader[4].is_alive) {
+        lowest_invader_row_alive = large;
+    } else if (medium_invader[0].is_alive || medium_invader[1].is_alive || medium_invader[2].is_alive || medium_invader[3].is_alive || medium_invader[4].is_alive) {
+        lowest_invader_row_alive = medium;
+    } else {
+        lowest_invader_row_alive = small;
+    }
+    //If an invader touches the bottom the game ends, otherwise the invaders descend
+    if (small_invader[0].y_pos < 39 - (7*lowest_invader_row_alive)) {
+        for (int i = 0; i < 5; i++) {
+            small_invader[i].y_pos += 3;
+            medium_invader[i].y_pos += 3;
+            large_invader[i].y_pos += 3;
+            invader_direction = new_direction;
+        }
+    } else {
+        game_over = true;
+    }
+
+    //TEST CODE
+    down_count++;
+}
+
+/*
+void InitUFO()
+{
+
+}
+*/
+
+void DrawUFO()
+{
+    //Draws the UFO
+    int x_pos = 20;
+    int y_pos = 25;
+    for (int col = 0; col < col_no; col++) {
+        for (int row = 0; row < row_no; row++) {
+            if(ufo_bitmap[row][col]) {
+                //lcd.setPixel(x_pos + col, y_pos + row);
+                screen_map[x_pos + col][y_pos + row] = UFO;
+            }
+        }
+    }
 }
\ No newline at end of file