Space Invaders - Embedded Systems Project 15/16 - Avinash Patel 200860407
Dependencies: Joystick N5110 SDFileSystem mbed
Diff: main.cpp
- Revision:
- 2:d34c95990605
- Parent:
- 1:b300d052d549
- Child:
- 3:544b59d60ab8
diff -r b300d052d549 -r d34c95990605 main.cpp --- 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