Daniel Martin / Mbed 2 deprecated space_invaders_pvp

Dependencies:   mbed mbed-rtos 4DGL-uLCD-SE

Committer:
dmartin99
Date:
Sun May 02 19:01:00 2021 +0000
Revision:
12:f49bae848977
Parent:
11:0309bef74ba8
Working Code of PvP Space Invaders

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dmartin99 12:f49bae848977 1 // Copyright (c) 2015 Devon Cooper and Sidak Dhillon
dmartin99 12:f49bae848977 2 //
dmartin99 12:f49bae848977 3 // Permission is hereby granted, free of charge, to any person obtaining
dmartin99 12:f49bae848977 4 // a copy of this software and associated documentation files (the
dmartin99 12:f49bae848977 5 // "Software"), to deal in the Software without restriction, including
dmartin99 12:f49bae848977 6 // without limitation the rights to use, copy, modify, merge, publish,
dmartin99 12:f49bae848977 7 // distribute, sublicense, and/or sell copies of the Software, and to
dmartin99 12:f49bae848977 8 // permit persons to whom the Software is furnished to do so, subject to
dmartin99 12:f49bae848977 9 // the following conditions:
dmartin99 12:f49bae848977 10 //
dmartin99 12:f49bae848977 11 // The above copyright notice and this permission notice shall be included
dmartin99 12:f49bae848977 12 // in all copies or substantial portions of the Software.
dmartin99 12:f49bae848977 13 //
dmartin99 12:f49bae848977 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
dmartin99 12:f49bae848977 15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
dmartin99 12:f49bae848977 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
dmartin99 12:f49bae848977 17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
dmartin99 12:f49bae848977 18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
dmartin99 12:f49bae848977 19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
dmartin99 12:f49bae848977 20 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
dmartin99 12:f49bae848977 21
emilmont 1:491820ee784d 22 #include "mbed.h"
dmartin99 12:f49bae848977 23 #include "uLCD_4DGL.h"
dmartin99 12:f49bae848977 24
dmartin99 12:f49bae848977 25 // LCD
dmartin99 12:f49bae848977 26 uLCD_4DGL uLCD(p28, p27, p30); // serial tx, serial rx, reset pin;
dmartin99 12:f49bae848977 27
dmartin99 12:f49bae848977 28 // Input Devices
dmartin99 12:f49bae848977 29 DigitalIn fire_button(p22, PullUp);
dmartin99 12:f49bae848977 30 // Note: p15 is attached to VERT and p16 is attached to HORZ, however horizontal movement
dmartin99 12:f49bae848977 31 // triggers VERT and vertical movement triggers HORZ, so they are switched here.
dmartin99 12:f49bae848977 32 AnalogIn horizontal_in(p15);
dmartin99 12:f49bae848977 33 AnalogIn vertical_in(p16);
dmartin99 12:f49bae848977 34
dmartin99 12:f49bae848977 35 #define SCREEN_MAX_X 128
dmartin99 12:f49bae848977 36 #define SCREEN_MAX_Y 128
dmartin99 12:f49bae848977 37
dmartin99 12:f49bae848977 38 #define BLACK 0x000000
dmartin99 12:f49bae848977 39 #define SHIP_COLOR 0xFFFFFF
dmartin99 12:f49bae848977 40 #define SHIP_COLOR2 0xFFF00F
dmartin99 12:f49bae848977 41 #define SHIP_DAMAGED_COLOR 0xFF0000
dmartin99 12:f49bae848977 42 #define BARRICADE_COLOR 0xFF00FF
dmartin99 12:f49bae848977 43 #define BULLET_COLOR 0x00FF00
dmartin99 12:f49bae848977 44 #define ALIEN_COLOR 0x00FFFF
dmartin99 12:f49bae848977 45
dmartin99 12:f49bae848977 46 #define SHIP_WIDTH 16
dmartin99 12:f49bae848977 47 #define SHIP_HEIGHT 8
dmartin99 12:f49bae848977 48 #define SHIP_GUN_WIDTH 3
dmartin99 12:f49bae848977 49 #define SHIP_GUN_HEIGHT 3
dmartin99 12:f49bae848977 50
dmartin99 12:f49bae848977 51 #define BULLET_WIDTH 1
dmartin99 12:f49bae848977 52 #define BULLET_HEIGHT 3
dmartin99 12:f49bae848977 53
dmartin99 12:f49bae848977 54 #define BARRICADES_START_Y (SCREEN_MAX_Y - 32)
dmartin99 12:f49bae848977 55 #define BARRICADES_END_Y (SCREEN_MAX_Y - 16)
dmartin99 12:f49bae848977 56 #define BARRICADE_SIZE 16
dmartin99 12:f49bae848977 57
dmartin99 12:f49bae848977 58 #define ALIEN_HEIGHT 8
dmartin99 12:f49bae848977 59 #define ALIEN_WIDTH 11
dmartin99 12:f49bae848977 60 #define ALIEN_SCORE_AMOUNT 10
dmartin99 12:f49bae848977 61
dmartin99 12:f49bae848977 62 /***** Sprite Data ***********************************************************/
dmartin99 12:f49bae848977 63
dmartin99 12:f49bae848977 64 #define _ BLACK
dmartin99 12:f49bae848977 65 #define X BARRICADE_COLOR
dmartin99 12:f49bae848977 66 const int barricade_sprite[BARRICADE_SIZE * BARRICADE_SIZE] = {
dmartin99 12:f49bae848977 67 _,_,_,X,X,X,X,X,X,X,X,X,X,_,_,_,
dmartin99 12:f49bae848977 68 _,_,X,X,X,X,X,X,X,X,X,X,X,X,_,_,
dmartin99 12:f49bae848977 69 _,X,X,X,X,X,X,X,X,X,X,X,X,X,X,_,
dmartin99 12:f49bae848977 70 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 71 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 72 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 73 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 74 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 75 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 76 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 77 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 78 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 79 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 80 X,X,X,X,X,X,X,_,_,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 81 X,X,X,X,X,_,_,_,_,_,_,X,X,X,X,X,
dmartin99 12:f49bae848977 82 X,X,X,X,_,_,_,_,_,_,_,_,X,X,X,X,
dmartin99 12:f49bae848977 83 };
dmartin99 12:f49bae848977 84 #undef _
dmartin99 12:f49bae848977 85 #undef X
dmartin99 12:f49bae848977 86
dmartin99 12:f49bae848977 87 #define _ 0x000000
dmartin99 12:f49bae848977 88 #define X 0x00FFFF
dmartin99 12:f49bae848977 89 #define Q 0xFF0F0F
dmartin99 12:f49bae848977 90 const int alien_sprite_1[ALIEN_HEIGHT * ALIEN_WIDTH] = {
dmartin99 12:f49bae848977 91 _,_,X,_,_,_,_,_,X,_,_,
dmartin99 12:f49bae848977 92 _,_,_,X,_,_,_,X,_,_,_,
dmartin99 12:f49bae848977 93 _,_,X,X,X,X,X,X,X,_,_,
dmartin99 12:f49bae848977 94 _,X,X,_,X,X,X,_,X,X,_,
dmartin99 12:f49bae848977 95 X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 96 X,_,X,X,X,X,X,X,X,_,X,
dmartin99 12:f49bae848977 97 X,_,X,_,_,_,_,_,X,_,X,
dmartin99 12:f49bae848977 98 _,_,_,X,X,_,X,X,_,_,_,
dmartin99 12:f49bae848977 99 };
dmartin99 12:f49bae848977 100
dmartin99 12:f49bae848977 101 const int alien_sprite_flip[ALIEN_HEIGHT * ALIEN_WIDTH] = {
dmartin99 12:f49bae848977 102 _,_,_,Q,Q,_,Q,Q,_,_,_,
dmartin99 12:f49bae848977 103 Q,_,Q,_,_,_,_,_,Q,_,Q,
dmartin99 12:f49bae848977 104 Q,_,Q,Q,Q,Q,Q,Q,Q,_,Q,
dmartin99 12:f49bae848977 105 Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,Q,
dmartin99 12:f49bae848977 106 _,Q,Q,_,Q,Q,Q,_,Q,Q,_,
dmartin99 12:f49bae848977 107 _,_,Q,Q,Q,Q,Q,Q,Q,_,_,
dmartin99 12:f49bae848977 108 _,_,_,Q,_,_,_,Q,_,_,_,
dmartin99 12:f49bae848977 109 _,_,Q,_,_,_,_,_,Q,_,_,
dmartin99 12:f49bae848977 110 };
dmartin99 12:f49bae848977 111
dmartin99 12:f49bae848977 112 const int alien_sprite_2[ALIEN_HEIGHT * ALIEN_WIDTH] = {
dmartin99 12:f49bae848977 113 _,_,_,_,X,X,X,_,_,_,_,
dmartin99 12:f49bae848977 114 _,X,X,X,X,X,X,X,X,X,_,
dmartin99 12:f49bae848977 115 X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 116 X,X,X,_,_,X,_,_,X,X,X,
dmartin99 12:f49bae848977 117 X,X,X,X,X,X,X,X,X,X,X,
dmartin99 12:f49bae848977 118 _,_,_,X,X,_,X,X,_,_,_,
dmartin99 12:f49bae848977 119 _,_,X,X,_,_,_,X,X,_,_,
dmartin99 12:f49bae848977 120 X,X,_,_,_,X,_,_,_,X,X,
dmartin99 12:f49bae848977 121 };
dmartin99 12:f49bae848977 122
dmartin99 12:f49bae848977 123 const int alien_sprite_3[ALIEN_HEIGHT * ALIEN_WIDTH] = {
dmartin99 12:f49bae848977 124 _,_,_,_,_,X,X,_,_,_,_,
dmartin99 12:f49bae848977 125 _,_,_,_,X,X,X,X,_,_,_,
dmartin99 12:f49bae848977 126 _,_,_,X,X,X,X,X,X,_,_,
dmartin99 12:f49bae848977 127 _,_,X,X,_,X,X,_,X,X,_,
dmartin99 12:f49bae848977 128 _,_,X,X,X,X,X,X,X,X,_,
dmartin99 12:f49bae848977 129 _,_,_,_,X,_,_,X,_,_,_,
dmartin99 12:f49bae848977 130 _,_,_,X,_,X,X,_,X,_,_,
dmartin99 12:f49bae848977 131 _,_,X,_,X,_,_,X,_,X,_,
dmartin99 12:f49bae848977 132 };
dmartin99 12:f49bae848977 133
dmartin99 12:f49bae848977 134 const int blank[ALIEN_HEIGHT * ALIEN_WIDTH] = {
dmartin99 12:f49bae848977 135 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 136 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 137 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 138 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 139 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 140 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 141 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 142 _,_,_,_,_,_,_,_,_,_,_,
dmartin99 12:f49bae848977 143 };
dmartin99 12:f49bae848977 144 #undef _
dmartin99 12:f49bae848977 145 #undef X
dmartin99 12:f49bae848977 146
dmartin99 12:f49bae848977 147 enum AlienSpecies {
dmartin99 12:f49bae848977 148 ALIEN_SPECIES_1, ALIEN_SPECIES_2, ALIEN_SPECIES_3,
dmartin99 12:f49bae848977 149 };
dmartin99 12:f49bae848977 150 #define ALIEN_ROW_TO_SPECIES(_row) \
dmartin99 12:f49bae848977 151 ((_row) == 0 ? ALIEN_SPECIES_3 : (_row) < 3 ? ALIEN_SPECIES_2 : ALIEN_SPECIES_1)
dmartin99 12:f49bae848977 152
dmartin99 12:f49bae848977 153 // Input Device State
dmartin99 12:f49bae848977 154 volatile bool fire_button_pressed;
dmartin99 12:f49bae848977 155 volatile bool fire_button_pressed2;
dmartin99 12:f49bae848977 156 volatile float horizontal_movement;
dmartin99 12:f49bae848977 157 volatile float vertical_movement;
dmartin99 12:f49bae848977 158 volatile float horizontal_movement2;
dmartin99 12:f49bae848977 159
dmartin99 12:f49bae848977 160 Ticker input_ticker;
dmartin99 12:f49bae848977 161
dmartin99 12:f49bae848977 162 // Barricade state
dmartin99 12:f49bae848977 163 bool barricades[SCREEN_MAX_X][BARRICADE_SIZE];
dmartin99 12:f49bae848977 164
dmartin99 12:f49bae848977 165 // Player state
dmartin99 12:f49bae848977 166 bool player_alive;
dmartin99 12:f49bae848977 167 bool player_alive2;
dmartin99 12:f49bae848977 168 int player_x;
dmartin99 12:f49bae848977 169 int player_x2;
dmartin99 12:f49bae848977 170 bool player_bullet_exists;
dmartin99 12:f49bae848977 171 int player_bullet_x;
dmartin99 12:f49bae848977 172 int player_bullet_y;
dmartin99 12:f49bae848977 173 bool player_bullet_exists2;
dmartin99 12:f49bae848977 174 int player_bullet_x2;
dmartin99 12:f49bae848977 175 int player_bullet_y2;
dmartin99 12:f49bae848977 176 int player_score;
dmartin99 12:f49bae848977 177 int player_lives;
dmartin99 12:f49bae848977 178
dmartin99 12:f49bae848977 179 // Alien state
dmartin99 12:f49bae848977 180 bool aliens[5][5];
dmartin99 12:f49bae848977 181 int aliens_x; // left-most
dmartin99 12:f49bae848977 182 int aliens_y; // bottom-most
dmartin99 12:f49bae848977 183 struct { bool exists; int x; int y; } alien_bullets[3];
dmartin99 12:f49bae848977 184
dmartin99 12:f49bae848977 185 // Random seed
dmartin99 12:f49bae848977 186 unsigned int random_seed;
dmartin99 12:f49bae848977 187 bool random_seeded;
dmartin99 12:f49bae848977 188
dmartin99 12:f49bae848977 189 int pvp_state = -1;
dmartin99 12:f49bae848977 190
dmartin99 12:f49bae848977 191 RawSerial dev(p13,p14);
dmartin99 12:f49bae848977 192 BusOut myled(LED1,LED2,LED3,LED4);
dmartin99 12:f49bae848977 193 DigitalOut them_led(p24);
dmartin99 12:f49bae848977 194 DigitalOut us_led(p20);
dmartin99 12:f49bae848977 195
dmartin99 12:f49bae848977 196 void left_blue() {
dmartin99 12:f49bae848977 197 horizontal_movement2 -= 1;
dmartin99 12:f49bae848977 198 }
dmartin99 12:f49bae848977 199
dmartin99 12:f49bae848977 200 void right_blue() {
dmartin99 12:f49bae848977 201 horizontal_movement2 += 1;
dmartin99 12:f49bae848977 202 }
dmartin99 12:f49bae848977 203
dmartin99 12:f49bae848977 204 Ticker flipper;
dmartin99 12:f49bae848977 205
dmartin99 12:f49bae848977 206 void dev_recv()
dmartin99 12:f49bae848977 207 {
dmartin99 12:f49bae848977 208 char bnum=0;
dmartin99 12:f49bae848977 209 while(dev.readable()) {
dmartin99 12:f49bae848977 210 if (dev.getc()=='!') {
dmartin99 12:f49bae848977 211 if (dev.getc()=='B') { //button data
dmartin99 12:f49bae848977 212 bnum = dev.getc(); //button number
dmartin99 12:f49bae848977 213 if ((bnum>='5')&&(bnum<='8')) { //is a number button 1..4
dmartin99 12:f49bae848977 214 player_alive2 = true;
dmartin99 12:f49bae848977 215 bool on = dev.getc()-'0';
dmartin99 12:f49bae848977 216 myled[bnum-'5']= on; //turn on/off that num LED
dmartin99 12:f49bae848977 217 if (on) {
dmartin99 12:f49bae848977 218 if(bnum=='5')
dmartin99 12:f49bae848977 219 fire_button_pressed2 = 1;
dmartin99 12:f49bae848977 220 else if(bnum=='7')
dmartin99 12:f49bae848977 221 flipper.attach(&left_blue, 0.02);
dmartin99 12:f49bae848977 222 else if(bnum=='8')
dmartin99 12:f49bae848977 223 flipper.attach(&right_blue, 0.02);
dmartin99 12:f49bae848977 224 } else {
dmartin99 12:f49bae848977 225 flipper.detach();
dmartin99 12:f49bae848977 226 }
dmartin99 12:f49bae848977 227 }
dmartin99 12:f49bae848977 228 }
dmartin99 12:f49bae848977 229 }
dmartin99 12:f49bae848977 230 }
dmartin99 12:f49bae848977 231 }
dmartin99 12:f49bae848977 232
dmartin99 12:f49bae848977 233 // Audio
dmartin99 12:f49bae848977 234 #include "SongPlayer.h"
mbed_official 11:0309bef74ba8 235 #include "rtos.h"
dmartin99 12:f49bae848977 236
dmartin99 12:f49bae848977 237 float game_over_note[18]= {884.0, 798.45, 722.25, 722.25, 798.45, 884.0, 884.0, 884.0, 798.45, 722.25, 798.45, 884.0, 798.45, 722.25, 687.35, 722.25, 722.25, 100.0 };
dmartin99 12:f49bae848977 238 float game_over_duration[18]= {0.6384, 0.3192, 0.9576, 0.6384, 0.3192, 0.6384, 0.3192, 0.3192, 0.3192, 0.3192, 0.3192, 0.3192, 0.3192, 0.6384, 0.3192, 0.6384, 0.6384, 0.0 };
dmartin99 12:f49bae848977 239
dmartin99 12:f49bae848977 240 float shootNote[1] = {950.0};
dmartin99 12:f49bae848977 241 float durationNote[1] = {0.15};
dmartin99 12:f49bae848977 242
dmartin99 12:f49bae848977 243 float hitNote[2] = {1400.0, 1400.0};
dmartin99 12:f49bae848977 244 float hit_durationNote[2] = {0.15, 0.15};
dmartin99 12:f49bae848977 245
dmartin99 12:f49bae848977 246 SongPlayer mySpeaker(p21);
dmartin99 12:f49bae848977 247
dmartin99 12:f49bae848977 248 volatile int isPlaying = -1;
dmartin99 12:f49bae848977 249 Mutex isPlaying_mutex;
dmartin99 12:f49bae848977 250
dmartin99 12:f49bae848977 251 Thread audio_thread;
dmartin99 12:f49bae848977 252
dmartin99 12:f49bae848977 253 void audio_thread_run() {
emilmont 1:491820ee784d 254 while (true) {
dmartin99 12:f49bae848977 255 isPlaying_mutex.lock();
dmartin99 12:f49bae848977 256 if (isPlaying == -1) {
dmartin99 12:f49bae848977 257 isPlaying_mutex.unlock();
dmartin99 12:f49bae848977 258 } else {
dmartin99 12:f49bae848977 259
dmartin99 12:f49bae848977 260 int songID = isPlaying;
dmartin99 12:f49bae848977 261
dmartin99 12:f49bae848977 262 isPlaying = 0;
dmartin99 12:f49bae848977 263 isPlaying_mutex.unlock();
dmartin99 12:f49bae848977 264
dmartin99 12:f49bae848977 265
dmartin99 12:f49bae848977 266 if (songID == 1 ) {
dmartin99 12:f49bae848977 267 mySpeaker.PlaySong(shootNote, durationNote);
dmartin99 12:f49bae848977 268 } else if (songID == 2 ) {
dmartin99 12:f49bae848977 269 us_led = 1;
dmartin99 12:f49bae848977 270 mySpeaker.PlaySong(hitNote, hit_durationNote);
dmartin99 12:f49bae848977 271 Thread::wait(500);
dmartin99 12:f49bae848977 272 us_led = 0;
dmartin99 12:f49bae848977 273
dmartin99 12:f49bae848977 274 } else if (songID == 3 ) {
dmartin99 12:f49bae848977 275 us_led = 1;
dmartin99 12:f49bae848977 276 them_led = 1;
dmartin99 12:f49bae848977 277 mySpeaker.PlaySong(game_over_note, game_over_duration);
dmartin99 12:f49bae848977 278 Thread::wait(500);
dmartin99 12:f49bae848977 279 us_led = 0;
dmartin99 12:f49bae848977 280 them_led = 0;
dmartin99 12:f49bae848977 281
dmartin99 12:f49bae848977 282 }else if (songID == 5 ) {
dmartin99 12:f49bae848977 283 them_led = 1;
dmartin99 12:f49bae848977 284 mySpeaker.PlaySong(hitNote, hit_durationNote);
dmartin99 12:f49bae848977 285 Thread::wait(500);
dmartin99 12:f49bae848977 286 them_led = 0;
dmartin99 12:f49bae848977 287 }
dmartin99 12:f49bae848977 288
dmartin99 12:f49bae848977 289 //mySpeaker.PlaySong(shootNote, durationNote);
dmartin99 12:f49bae848977 290
dmartin99 12:f49bae848977 291 isPlaying_mutex.lock();
dmartin99 12:f49bae848977 292 isPlaying = -1;
dmartin99 12:f49bae848977 293 isPlaying_mutex.unlock();
dmartin99 12:f49bae848977 294 }
dmartin99 12:f49bae848977 295
dmartin99 12:f49bae848977 296 Thread::wait(100);
dmartin99 12:f49bae848977 297 }
dmartin99 12:f49bae848977 298 }
dmartin99 12:f49bae848977 299
dmartin99 12:f49bae848977 300
dmartin99 12:f49bae848977 301 void add_audio(int song_id) {
dmartin99 12:f49bae848977 302 isPlaying_mutex.lock();
dmartin99 12:f49bae848977 303 int isSongPlaying = isPlaying;
dmartin99 12:f49bae848977 304
dmartin99 12:f49bae848977 305 if (isSongPlaying == 0) {
dmartin99 12:f49bae848977 306 isPlaying_mutex.unlock();
dmartin99 12:f49bae848977 307 return;
dmartin99 12:f49bae848977 308 }
dmartin99 12:f49bae848977 309
dmartin99 12:f49bae848977 310 isPlaying = song_id;
dmartin99 12:f49bae848977 311 isPlaying_mutex.unlock();
dmartin99 12:f49bae848977 312 }
dmartin99 12:f49bae848977 313
dmartin99 12:f49bae848977 314
dmartin99 12:f49bae848977 315 /***** Rendering Routines ****************************************************/
dmartin99 12:f49bae848977 316
dmartin99 12:f49bae848977 317 /* The player is drawn as two rectangles, one for the main body, and one for
dmartin99 12:f49bae848977 318 * the cannon.
dmartin99 12:f49bae848977 319 */
dmartin99 12:f49bae848977 320 void draw_player(int center_x, int color) {
dmartin99 12:f49bae848977 321 uLCD.filled_rectangle(
dmartin99 12:f49bae848977 322 center_x - (SHIP_WIDTH / 2),
dmartin99 12:f49bae848977 323 SCREEN_MAX_Y - SHIP_HEIGHT,
dmartin99 12:f49bae848977 324 center_x + (SHIP_WIDTH / 2),
dmartin99 12:f49bae848977 325 SCREEN_MAX_Y - 1,
dmartin99 12:f49bae848977 326 color);
dmartin99 12:f49bae848977 327 uLCD.filled_rectangle(
dmartin99 12:f49bae848977 328 center_x - (SHIP_GUN_WIDTH / 2),
dmartin99 12:f49bae848977 329 SCREEN_MAX_Y - (SHIP_HEIGHT + SHIP_GUN_HEIGHT),
dmartin99 12:f49bae848977 330 center_x + (SHIP_GUN_WIDTH / 2),
dmartin99 12:f49bae848977 331 SCREEN_MAX_Y - SHIP_HEIGHT,
dmartin99 12:f49bae848977 332 color);
dmartin99 12:f49bae848977 333 }
dmartin99 12:f49bae848977 334
dmartin99 12:f49bae848977 335 /* Aliens are drawn using the sprite data and the uLCD's BLIT mode. */
dmartin99 12:f49bae848977 336 void draw_alien(AlienSpecies species, int left_x, int bottom_y) {
dmartin99 12:f49bae848977 337 const int *sprite =
dmartin99 12:f49bae848977 338 species == ALIEN_SPECIES_1 ? alien_sprite_1 :
dmartin99 12:f49bae848977 339 species == ALIEN_SPECIES_2 ? alien_sprite_2 :
dmartin99 12:f49bae848977 340 alien_sprite_3;
dmartin99 12:f49bae848977 341 uLCD.BLIT(left_x, bottom_y, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)sprite);
dmartin99 12:f49bae848977 342 }
dmartin99 12:f49bae848977 343
dmartin99 12:f49bae848977 344 /* Erase an alien. This is a special routine because aliens have sprites
dmartin99 12:f49bae848977 345 * and so take more time to draw than other objects.
dmartin99 12:f49bae848977 346 */
dmartin99 12:f49bae848977 347 void erase_alien(int left_x, int bottom_y) {
dmartin99 12:f49bae848977 348 // We erase an extra 2 around the sides and bottom to account for movement.
dmartin99 12:f49bae848977 349 // This should be safe because the aliens never get closer than 8 pixels to
dmartin99 12:f49bae848977 350 // the edge of the LCD.
dmartin99 12:f49bae848977 351 uLCD.filled_rectangle(left_x - 2, bottom_y, left_x + 11 + 2, bottom_y + 8 + 2, BLACK);
dmartin99 12:f49bae848977 352 }
dmartin99 12:f49bae848977 353
dmartin99 12:f49bae848977 354 /* Draws all 25 aliens. (5 rows, 5 columns) */
dmartin99 12:f49bae848977 355 void draw_aliens() {
dmartin99 12:f49bae848977 356 uLCD.filled_rectangle(aliens_x, aliens_y, aliens_x + 16 * 5, aliens_y + 12 * 5, BLACK);
dmartin99 12:f49bae848977 357 wait(0.05);
dmartin99 12:f49bae848977 358
dmartin99 12:f49bae848977 359 for (int x = 0; x < 5; x++) {
dmartin99 12:f49bae848977 360 for (int y = 0; y < 5; y++) {
dmartin99 12:f49bae848977 361 if (aliens[x][y]) {
dmartin99 12:f49bae848977 362 draw_alien(ALIEN_ROW_TO_SPECIES(y), aliens_x + 16 * x, aliens_y + 12 * y);
dmartin99 12:f49bae848977 363 }
dmartin99 12:f49bae848977 364 }
dmartin99 12:f49bae848977 365 }
dmartin99 12:f49bae848977 366 }
dmartin99 12:f49bae848977 367
dmartin99 12:f49bae848977 368 /* Draw a bullet. A bullet is drawn as a 1x3 vertical line. */
dmartin99 12:f49bae848977 369 void draw_bullet(int center_x, int bottom_y, int color) {
dmartin99 12:f49bae848977 370 uLCD.line(
dmartin99 12:f49bae848977 371 center_x,
dmartin99 12:f49bae848977 372 bottom_y,
dmartin99 12:f49bae848977 373 center_x,
dmartin99 12:f49bae848977 374 bottom_y + BULLET_HEIGHT,
dmartin99 12:f49bae848977 375 color);
dmartin99 12:f49bae848977 376 }
dmartin99 12:f49bae848977 377
dmartin99 12:f49bae848977 378 /***** Initialization ********************************************************/
dmartin99 12:f49bae848977 379 void initialize_screen() {
dmartin99 12:f49bae848977 380 // Attempting to use a higher baud rate causes errors (the LCD freezes).
dmartin99 12:f49bae848977 381 uLCD.baudrate(57600);
dmartin99 12:f49bae848977 382 uLCD.background_color(BLACK);
dmartin99 12:f49bae848977 383 uLCD.cls();
dmartin99 12:f49bae848977 384 }
dmartin99 12:f49bae848977 385
dmartin99 12:f49bae848977 386
dmartin99 12:f49bae848977 387 volatile float init_movement = 0;
dmartin99 12:f49bae848977 388 volatile float init_movement2 = 0;
dmartin99 12:f49bae848977 389 bool first_call = true;
dmartin99 12:f49bae848977 390 void __input_ticker__() {
dmartin99 12:f49bae848977 391 // while(true) {
dmartin99 12:f49bae848977 392 if (first_call) {
dmartin99 12:f49bae848977 393 init_movement = horizontal_in;
dmartin99 12:f49bae848977 394 init_movement2 = vertical_in;
dmartin99 12:f49bae848977 395 first_call = false;
dmartin99 12:f49bae848977 396 }
dmartin99 12:f49bae848977 397 fire_button_pressed |= !fire_button;
dmartin99 12:f49bae848977 398 horizontal_movement += horizontal_in - init_movement;
dmartin99 12:f49bae848977 399 vertical_movement += vertical_in - init_movement2;
dmartin99 12:f49bae848977 400 if (fire_button_pressed)
dmartin99 12:f49bae848977 401 player_alive = true;
dmartin99 12:f49bae848977 402 // Thread::wait(100);
dmartin99 12:f49bae848977 403 // }
dmartin99 12:f49bae848977 404 }
dmartin99 12:f49bae848977 405
dmartin99 12:f49bae848977 406 Thread movement;
dmartin99 12:f49bae848977 407
dmartin99 12:f49bae848977 408 // We use interrupts for measuring input so that input remains responsive even
dmartin99 12:f49bae848977 409 // when the graphics are lagging.
dmartin99 12:f49bae848977 410 void initialize_input() {
dmartin99 12:f49bae848977 411 input_ticker.detach();
dmartin99 12:f49bae848977 412 input_ticker.attach(__input_ticker__, 0.005);
dmartin99 12:f49bae848977 413 // movement.start(__input_ticker__);
dmartin99 12:f49bae848977 414 // START;
dmartin99 12:f49bae848977 415 }
dmartin99 12:f49bae848977 416
dmartin99 12:f49bae848977 417 void initialize_player() {
dmartin99 12:f49bae848977 418 player_x = 2 * SCREEN_MAX_X / 3;
dmartin99 12:f49bae848977 419 player_bullet_exists = false;
dmartin99 12:f49bae848977 420 draw_player(player_x, SHIP_COLOR);
dmartin99 12:f49bae848977 421 player_score = 0;
dmartin99 12:f49bae848977 422 player_lives = 2;
dmartin99 12:f49bae848977 423
dmartin99 12:f49bae848977 424 uLCD.locate(0, 0);
dmartin99 12:f49bae848977 425 uLCD.printf("Score:%i", player_score);
dmartin99 12:f49bae848977 426
dmartin99 12:f49bae848977 427 uLCD.locate(10, 0);
dmartin99 12:f49bae848977 428 uLCD.printf("Lives:%i", player_lives);
dmartin99 12:f49bae848977 429 }
dmartin99 12:f49bae848977 430
dmartin99 12:f49bae848977 431 void initialize_player2() {
dmartin99 12:f49bae848977 432 player_x2 = SCREEN_MAX_X / 3;
dmartin99 12:f49bae848977 433 draw_player(player_x2, SHIP_COLOR2);
dmartin99 12:f49bae848977 434 }
dmartin99 12:f49bae848977 435
dmartin99 12:f49bae848977 436 void initialize_player3() {
dmartin99 12:f49bae848977 437 player_x = SCREEN_MAX_X/2;
dmartin99 12:f49bae848977 438 const int *sprite = alien_sprite_1;
dmartin99 12:f49bae848977 439 uLCD.BLIT(player_x, SCREEN_MAX_Y-ALIEN_HEIGHT, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)sprite);
dmartin99 12:f49bae848977 440 }
dmartin99 12:f49bae848977 441
dmartin99 12:f49bae848977 442 void initialize_player4() {
dmartin99 12:f49bae848977 443 player_x2 = SCREEN_MAX_X/2;
dmartin99 12:f49bae848977 444 const int *sprite = alien_sprite_flip;
dmartin99 12:f49bae848977 445 uLCD.BLIT(player_x2, ALIEN_HEIGHT, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)sprite);
dmartin99 12:f49bae848977 446 }
dmartin99 12:f49bae848977 447
dmartin99 12:f49bae848977 448 void initialize_aliens() {
dmartin99 12:f49bae848977 449 // Start the aliens in the upper-left corner of the screen
dmartin99 12:f49bae848977 450 aliens_x = 8;
dmartin99 12:f49bae848977 451 aliens_y = 8;
dmartin99 12:f49bae848977 452
dmartin99 12:f49bae848977 453 for (int x = 0; x < 5; x++) {
dmartin99 12:f49bae848977 454 for (int y = 0; y < 5; y++) {
dmartin99 12:f49bae848977 455 aliens[x][y] = true;
dmartin99 12:f49bae848977 456 }
dmartin99 12:f49bae848977 457 }
dmartin99 12:f49bae848977 458
dmartin99 12:f49bae848977 459 for (int i = 0; i < 3; i++) {
dmartin99 12:f49bae848977 460 alien_bullets[i].exists = false;
dmartin99 12:f49bae848977 461 }
dmartin99 12:f49bae848977 462
dmartin99 12:f49bae848977 463 draw_aliens();
dmartin99 12:f49bae848977 464 }
dmartin99 12:f49bae848977 465
dmartin99 12:f49bae848977 466 void initialize_barricades() {
dmartin99 12:f49bae848977 467 memset(barricades, 0, sizeof(bool) * SCREEN_MAX_X * BARRICADE_SIZE);
dmartin99 12:f49bae848977 468
dmartin99 12:f49bae848977 469 for (int i = 1; i < 5; i++) {
dmartin99 12:f49bae848977 470 int start_x = (SCREEN_MAX_X * i / 5) - (BARRICADE_SIZE / 2);
dmartin99 12:f49bae848977 471
dmartin99 12:f49bae848977 472 uLCD.BLIT(start_x, BARRICADES_START_Y, BARRICADE_SIZE, BARRICADE_SIZE, (int*)barricade_sprite);
dmartin99 12:f49bae848977 473
dmartin99 12:f49bae848977 474 for (int x = 0; x < BARRICADE_SIZE; x++) {
dmartin99 12:f49bae848977 475 for (int y = 0; y < BARRICADE_SIZE; y++) {
dmartin99 12:f49bae848977 476 barricades[start_x + x][y] = !!barricade_sprite[y * BARRICADE_SIZE + x];
dmartin99 12:f49bae848977 477 }
dmartin99 12:f49bae848977 478 }
dmartin99 12:f49bae848977 479 }
dmartin99 12:f49bae848977 480 }
dmartin99 12:f49bae848977 481
dmartin99 12:f49bae848977 482 // Devices only need to be initialized once during the program, at start up
dmartin99 12:f49bae848977 483 void initialize_devices() {
dmartin99 12:f49bae848977 484 initialize_screen();
dmartin99 12:f49bae848977 485 initialize_input();
dmartin99 12:f49bae848977 486 }
dmartin99 12:f49bae848977 487
dmartin99 12:f49bae848977 488 // Game state needs to be re-initialized whenever a new game is started after
dmartin99 12:f49bae848977 489 // a game over or win.
dmartin99 12:f49bae848977 490 void initialize_game_state() {
dmartin99 12:f49bae848977 491 initialize_player();
dmartin99 12:f49bae848977 492 initialize_player2();
dmartin99 12:f49bae848977 493 initialize_barricades();
dmartin99 12:f49bae848977 494 initialize_aliens();
dmartin99 12:f49bae848977 495 }
dmartin99 12:f49bae848977 496
dmartin99 12:f49bae848977 497 void initialize_game_state2() {
dmartin99 12:f49bae848977 498 initialize_player3();
dmartin99 12:f49bae848977 499 initialize_player4();
dmartin99 12:f49bae848977 500 }
dmartin99 12:f49bae848977 501
dmartin99 12:f49bae848977 502
dmartin99 12:f49bae848977 503 /***** Logic *****************************************************************/
dmartin99 12:f49bae848977 504
dmartin99 12:f49bae848977 505 /* Causes a chunk of the barricade around the given x and y coordinates to
dmartin99 12:f49bae848977 506 * be destroyed.
dmartin99 12:f49bae848977 507 */
dmartin99 12:f49bae848977 508 void barricade_impact(int x, int y) {
dmartin99 12:f49bae848977 509 // This is supposed to create a diamond pattern around the point of
dmartin99 12:f49bae848977 510 // impact, but for some reason it creates a square.
dmartin99 12:f49bae848977 511 // Eg, it should be * but instead is *****
dmartin99 12:f49bae848977 512 // *** *****
dmartin99 12:f49bae848977 513 // ***** *****
dmartin99 12:f49bae848977 514 // *** *****
dmartin99 12:f49bae848977 515 // * *****
dmartin99 12:f49bae848977 516
dmartin99 12:f49bae848977 517 int x_dist = 2;
dmartin99 12:f49bae848977 518 for (int delta_x = -x_dist; delta_x <= x_dist; delta_x++) {
dmartin99 12:f49bae848977 519
dmartin99 12:f49bae848977 520 int y_dist = abs(x) == 2 ? 0 : abs(x) == 1 ? 1 : 2;
dmartin99 12:f49bae848977 521 for (int delta_y = -y_dist; delta_y <= y_dist; delta_y++) {
dmartin99 12:f49bae848977 522 int abs_x = x + delta_x;
dmartin99 12:f49bae848977 523 int abs_y = y + delta_y;
dmartin99 12:f49bae848977 524
dmartin99 12:f49bae848977 525 if (abs_x >= 0 && abs_x < SCREEN_MAX_X
dmartin99 12:f49bae848977 526 && abs_y >= BARRICADES_START_Y && abs_y < BARRICADES_END_Y) {
dmartin99 12:f49bae848977 527 barricades[abs_x][abs_y - BARRICADES_START_Y] = false;
dmartin99 12:f49bae848977 528 uLCD.pixel(abs_x, abs_y, BLACK);
dmartin99 12:f49bae848977 529 }
dmartin99 12:f49bae848977 530 }
emilmont 1:491820ee784d 531 }
emilmont 1:491820ee784d 532 }
dmartin99 12:f49bae848977 533
dmartin99 12:f49bae848977 534 /* Returns true if a bullet at the given coordinates hits an alien.
dmartin99 12:f49bae848977 535 * As a side effect, that alien is destroyed and the player's score is increased.
dmartin99 12:f49bae848977 536 */
dmartin99 12:f49bae848977 537 bool alien_impact(int x, int y) {
dmartin99 12:f49bae848977 538 int horizontal_region = (x - aliens_x) / 16;
dmartin99 12:f49bae848977 539 int vertical_region = (y - aliens_y) / 12;
dmartin99 12:f49bae848977 540
dmartin99 12:f49bae848977 541 int horizontal_offset = (x - aliens_x) % 16;
dmartin99 12:f49bae848977 542 int vertical_offset = (y - aliens_y) % 12;
dmartin99 12:f49bae848977 543
dmartin99 12:f49bae848977 544 if (horizontal_region >= 0 && horizontal_region < 5
dmartin99 12:f49bae848977 545 && vertical_region >= 0 && vertical_region < 5
dmartin99 12:f49bae848977 546 && aliens[horizontal_region][vertical_region]
dmartin99 12:f49bae848977 547 && horizontal_offset <= 11
dmartin99 12:f49bae848977 548 && vertical_offset <= 8) {
dmartin99 12:f49bae848977 549 aliens[horizontal_region][vertical_region] = false;
dmartin99 12:f49bae848977 550 erase_alien(aliens_x + 16 * horizontal_region, aliens_y + 12 * vertical_region);
dmartin99 12:f49bae848977 551 player_score += ALIEN_SCORE_AMOUNT;
dmartin99 12:f49bae848977 552 add_audio(5);
dmartin99 12:f49bae848977 553
dmartin99 12:f49bae848977 554 return true;
dmartin99 12:f49bae848977 555 } else {
dmartin99 12:f49bae848977 556 return false;
dmartin99 12:f49bae848977 557 }
dmartin99 12:f49bae848977 558 }
dmartin99 12:f49bae848977 559
dmartin99 12:f49bae848977 560 /* Returns true if a bullet at the given coordinates hits the player.
dmartin99 12:f49bae848977 561 * As a side effect, the player loses a life.
dmartin99 12:f49bae848977 562 */
dmartin99 12:f49bae848977 563 bool player_impact(int x, int y) {
dmartin99 12:f49bae848977 564 int player_y = SCREEN_MAX_Y;
dmartin99 12:f49bae848977 565 int player_y2 = pvp_state == -1 ? SCREEN_MAX_Y : 0;
dmartin99 12:f49bae848977 566 // if (y < SCREEN_MAX_Y && y >= SCREEN_MAX_Y - (SHIP_HEIGHT + SHIP_GUN_HEIGHT)) {
dmartin99 12:f49bae848977 567 if (x >= player_x - SHIP_WIDTH / 2 && x <= player_x + SHIP_WIDTH / 2 && y >= player_y - SHIP_HEIGHT / 2 && y <= player_y + SHIP_HEIGHT / 2) {
dmartin99 12:f49bae848977 568 if (pvp_state == -1)
dmartin99 12:f49bae848977 569 draw_player(player_x, SHIP_DAMAGED_COLOR);
dmartin99 12:f49bae848977 570 player_lives -= 1;
dmartin99 12:f49bae848977 571 add_audio(2);
dmartin99 12:f49bae848977 572
dmartin99 12:f49bae848977 573 return true;
dmartin99 12:f49bae848977 574 } else if (x >= player_x2 - SHIP_WIDTH / 2 && x <= player_x2 + SHIP_WIDTH / 2 && y >= player_y2 - SHIP_HEIGHT / 2 && y <= player_y2 + SHIP_HEIGHT / 2){
dmartin99 12:f49bae848977 575 if (pvp_state == -1)
dmartin99 12:f49bae848977 576 draw_player(player_x2, SHIP_DAMAGED_COLOR);
dmartin99 12:f49bae848977 577 player_lives -= 1;
dmartin99 12:f49bae848977 578 add_audio(2);
dmartin99 12:f49bae848977 579 return true;
dmartin99 12:f49bae848977 580 }
dmartin99 12:f49bae848977 581 // }
dmartin99 12:f49bae848977 582 return false;
dmartin99 12:f49bae848977 583 }
dmartin99 12:f49bae848977 584
dmartin99 12:f49bae848977 585 /* Checks if a barricade exists at the given x and y coordinates. */
dmartin99 12:f49bae848977 586 bool barricade_exist_at(int x, int y) {
dmartin99 12:f49bae848977 587 return y >= BARRICADES_START_Y && y < BARRICADES_END_Y && barricades[x][y - BARRICADES_START_Y];
dmartin99 12:f49bae848977 588 }
dmartin99 12:f49bae848977 589
dmartin99 12:f49bae848977 590 /***** Updates ***************************************************************/
dmartin99 12:f49bae848977 591
dmartin99 12:f49bae848977 592 // Uses C++ functors for the updates. The original idea was that each update
dmartin99 12:f49bae848977 593 // would return a continuation to allow more responsive updates to the player
dmartin99 12:f49bae848977 594 // object, but I realized it would be easier to just update the state in-place.
dmartin99 12:f49bae848977 595 // These should be turned into simple functions, but it works as it is now.
dmartin99 12:f49bae848977 596
dmartin99 12:f49bae848977 597 class PlayerUpdate {
dmartin99 12:f49bae848977 598 public:
dmartin99 12:f49bae848977 599 void operator()() {
dmartin99 12:f49bae848977 600 // Sample input devices
dmartin99 12:f49bae848977 601 float delta_x = horizontal_movement;
dmartin99 12:f49bae848977 602 horizontal_movement = 0;
dmartin99 12:f49bae848977 603
dmartin99 12:f49bae848977 604 // Update player
dmartin99 12:f49bae848977 605 int old_player_x = player_x;
dmartin99 12:f49bae848977 606 player_x += int(delta_x * 2);
dmartin99 12:f49bae848977 607
dmartin99 12:f49bae848977 608 if (player_x < SHIP_WIDTH / 2) player_x = SHIP_WIDTH / 2;
dmartin99 12:f49bae848977 609 if (player_x > SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1) player_x = SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1;
dmartin99 12:f49bae848977 610
dmartin99 12:f49bae848977 611 if (old_player_x != player_x) {
dmartin99 12:f49bae848977 612 draw_player(old_player_x, BLACK);
dmartin99 12:f49bae848977 613 draw_player(player_x, SHIP_COLOR);
dmartin99 12:f49bae848977 614 draw_player(player_x2, SHIP_COLOR2);
dmartin99 12:f49bae848977 615 }
dmartin99 12:f49bae848977 616 }
dmartin99 12:f49bae848977 617
dmartin99 12:f49bae848977 618 void alien() {
dmartin99 12:f49bae848977 619 // Sample input devices
dmartin99 12:f49bae848977 620 float delta_x = horizontal_movement;
dmartin99 12:f49bae848977 621 horizontal_movement = 0;
dmartin99 12:f49bae848977 622
dmartin99 12:f49bae848977 623 // Update player
dmartin99 12:f49bae848977 624 int old_player_x = player_x;
dmartin99 12:f49bae848977 625 player_x += int(delta_x * 2);
dmartin99 12:f49bae848977 626
dmartin99 12:f49bae848977 627 if (player_x < SHIP_WIDTH / 2) player_x = SHIP_WIDTH / 2;
dmartin99 12:f49bae848977 628 if (player_x > SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1) player_x = SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1;
dmartin99 12:f49bae848977 629
dmartin99 12:f49bae848977 630 if (old_player_x != player_x) {
dmartin99 12:f49bae848977 631 uLCD.BLIT(old_player_x, SCREEN_MAX_X - ALIEN_HEIGHT, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)blank);
dmartin99 12:f49bae848977 632 uLCD.BLIT(player_x, SCREEN_MAX_X - ALIEN_HEIGHT, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)alien_sprite_1);
dmartin99 12:f49bae848977 633 }
dmartin99 12:f49bae848977 634 }
dmartin99 12:f49bae848977 635 };
dmartin99 12:f49bae848977 636
dmartin99 12:f49bae848977 637 class PlayerUpdate2 {
dmartin99 12:f49bae848977 638 public:
dmartin99 12:f49bae848977 639 void operator()() {
dmartin99 12:f49bae848977 640 // Sample input devices
dmartin99 12:f49bae848977 641 float delta_x2 = horizontal_movement2;
dmartin99 12:f49bae848977 642 horizontal_movement2 = 0;
dmartin99 12:f49bae848977 643
dmartin99 12:f49bae848977 644 // Update player
dmartin99 12:f49bae848977 645 int old_player_x2 = player_x2;
dmartin99 12:f49bae848977 646 player_x2 += int(delta_x2 * 2);
dmartin99 12:f49bae848977 647
dmartin99 12:f49bae848977 648 if (player_x2 < SHIP_WIDTH / 2) player_x2 = SHIP_WIDTH / 2;
dmartin99 12:f49bae848977 649 if (player_x2 > SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1) player_x2 = SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1;
dmartin99 12:f49bae848977 650
dmartin99 12:f49bae848977 651 if (old_player_x2 != player_x2) {
dmartin99 12:f49bae848977 652 draw_player(old_player_x2, BLACK);
dmartin99 12:f49bae848977 653 draw_player(player_x, SHIP_COLOR);
dmartin99 12:f49bae848977 654 draw_player(player_x2, SHIP_COLOR2);
dmartin99 12:f49bae848977 655 }
dmartin99 12:f49bae848977 656 }
dmartin99 12:f49bae848977 657
dmartin99 12:f49bae848977 658 void alien() {
dmartin99 12:f49bae848977 659 // Sample input devices
dmartin99 12:f49bae848977 660 float delta_x2 = horizontal_movement2;
dmartin99 12:f49bae848977 661 horizontal_movement2 = 0;
dmartin99 12:f49bae848977 662
dmartin99 12:f49bae848977 663 // Update player
dmartin99 12:f49bae848977 664 int old_player_x2 = player_x2;
dmartin99 12:f49bae848977 665 player_x2 += int(delta_x2 * 2);
dmartin99 12:f49bae848977 666
dmartin99 12:f49bae848977 667 if (player_x2 < SHIP_WIDTH / 2) player_x2 = SHIP_WIDTH / 2;
dmartin99 12:f49bae848977 668 if (player_x2 > SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1) player_x2 = SCREEN_MAX_X - (SHIP_WIDTH / 2) - 1;
dmartin99 12:f49bae848977 669
dmartin99 12:f49bae848977 670 if (old_player_x2 != player_x2) {
dmartin99 12:f49bae848977 671 uLCD.BLIT(old_player_x2, ALIEN_HEIGHT, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)blank);
dmartin99 12:f49bae848977 672 uLCD.BLIT(player_x2, ALIEN_HEIGHT, ALIEN_WIDTH, ALIEN_HEIGHT, (int*)alien_sprite_flip);
dmartin99 12:f49bae848977 673 }
dmartin99 12:f49bae848977 674 }
dmartin99 12:f49bae848977 675 };
dmartin99 12:f49bae848977 676
dmartin99 12:f49bae848977 677 class AlienUpdate {
dmartin99 12:f49bae848977 678 // This one is a bit complicated, essentially it is a hard-coded state
dmartin99 12:f49bae848977 679 // machine that shifts one alien at a time so that the player can be
dmartin99 12:f49bae848977 680 // updated in between rows of aliens shifting.
dmartin99 12:f49bae848977 681
dmartin99 12:f49bae848977 682 enum State {
dmartin99 12:f49bae848977 683 SHIFTING_LEFT,
dmartin99 12:f49bae848977 684 SHIFTING_RIGHT,
dmartin99 12:f49bae848977 685 SHIFTING_DOWN_NEXT_IS_RIGHT,
dmartin99 12:f49bae848977 686 SHIFTING_DOWN_NEXT_IS_LEFT,
dmartin99 12:f49bae848977 687 } state;
dmartin99 12:f49bae848977 688 int row_shifting, column_shifting;
dmartin99 12:f49bae848977 689
dmartin99 12:f49bae848977 690 public:
dmartin99 12:f49bae848977 691 AlienUpdate() : state(SHIFTING_RIGHT), row_shifting(0), column_shifting(0) {}
dmartin99 12:f49bae848977 692
dmartin99 12:f49bae848977 693 void operator()() {
dmartin99 12:f49bae848977 694 switch (this->state) {
dmartin99 12:f49bae848977 695 case SHIFTING_LEFT:
dmartin99 12:f49bae848977 696 if (aliens[column_shifting][row_shifting]) {
dmartin99 12:f49bae848977 697 erase_alien(aliens_x + 16 * column_shifting, aliens_y + 12 * row_shifting);
dmartin99 12:f49bae848977 698 draw_alien(ALIEN_ROW_TO_SPECIES(row_shifting), aliens_x + 16 * column_shifting - 2, aliens_y + 12 * row_shifting);
dmartin99 12:f49bae848977 699 }
dmartin99 12:f49bae848977 700 column_shifting -= 1;
dmartin99 12:f49bae848977 701 if (column_shifting < 0) {
dmartin99 12:f49bae848977 702 if (row_shifting >= 4) {
dmartin99 12:f49bae848977 703 aliens_x -= 2;
dmartin99 12:f49bae848977 704 if (aliens_x < 8) {
dmartin99 12:f49bae848977 705 state = SHIFTING_DOWN_NEXT_IS_RIGHT;
dmartin99 12:f49bae848977 706 row_shifting = 0;
dmartin99 12:f49bae848977 707 column_shifting = 0;
dmartin99 12:f49bae848977 708 } else {
dmartin99 12:f49bae848977 709 row_shifting = 0;
dmartin99 12:f49bae848977 710 column_shifting = 4;
dmartin99 12:f49bae848977 711 }
dmartin99 12:f49bae848977 712 } else {
dmartin99 12:f49bae848977 713 row_shifting += 1;
dmartin99 12:f49bae848977 714 column_shifting = 4;
dmartin99 12:f49bae848977 715 }
dmartin99 12:f49bae848977 716 }
dmartin99 12:f49bae848977 717 break;
dmartin99 12:f49bae848977 718
dmartin99 12:f49bae848977 719 case SHIFTING_RIGHT:
dmartin99 12:f49bae848977 720 if (aliens[column_shifting][row_shifting]) {
dmartin99 12:f49bae848977 721 erase_alien(aliens_x + 16 * column_shifting, aliens_y + 12 * row_shifting);
dmartin99 12:f49bae848977 722 draw_alien(ALIEN_ROW_TO_SPECIES(row_shifting), aliens_x + 16 * column_shifting + 2, aliens_y + 12 * row_shifting);
dmartin99 12:f49bae848977 723 }
dmartin99 12:f49bae848977 724 column_shifting += 1;
dmartin99 12:f49bae848977 725 if (column_shifting > 4) {
dmartin99 12:f49bae848977 726 if (row_shifting >= 4) {
dmartin99 12:f49bae848977 727 aliens_x += 2;
dmartin99 12:f49bae848977 728 if (aliens_x > SCREEN_MAX_X - (16 * 5) - 8) {
dmartin99 12:f49bae848977 729 state = SHIFTING_DOWN_NEXT_IS_LEFT;
dmartin99 12:f49bae848977 730 row_shifting = 0;
dmartin99 12:f49bae848977 731 column_shifting = 0;
dmartin99 12:f49bae848977 732 } else {
dmartin99 12:f49bae848977 733 row_shifting = 0;
dmartin99 12:f49bae848977 734 column_shifting = 0;
dmartin99 12:f49bae848977 735 }
dmartin99 12:f49bae848977 736 } else {
dmartin99 12:f49bae848977 737 row_shifting += 1;
dmartin99 12:f49bae848977 738 column_shifting = 0;
dmartin99 12:f49bae848977 739 }
dmartin99 12:f49bae848977 740 }
dmartin99 12:f49bae848977 741 break;
dmartin99 12:f49bae848977 742
dmartin99 12:f49bae848977 743 case SHIFTING_DOWN_NEXT_IS_LEFT:
dmartin99 12:f49bae848977 744 case SHIFTING_DOWN_NEXT_IS_RIGHT:
dmartin99 12:f49bae848977 745 if (aliens[column_shifting][row_shifting]) {
dmartin99 12:f49bae848977 746 erase_alien(aliens_x + 16 * column_shifting, aliens_y + 12 * row_shifting);
dmartin99 12:f49bae848977 747 draw_alien(ALIEN_ROW_TO_SPECIES(row_shifting), aliens_x + 16 * column_shifting, aliens_y + 12 * row_shifting + 2);
dmartin99 12:f49bae848977 748 }
dmartin99 12:f49bae848977 749 column_shifting += 1;
dmartin99 12:f49bae848977 750 if (column_shifting > 4) {
dmartin99 12:f49bae848977 751 if (row_shifting >= 4) {
dmartin99 12:f49bae848977 752 if (this->state == SHIFTING_DOWN_NEXT_IS_LEFT) {
dmartin99 12:f49bae848977 753 state = SHIFTING_LEFT;
dmartin99 12:f49bae848977 754 column_shifting = 4;
dmartin99 12:f49bae848977 755 } else {
dmartin99 12:f49bae848977 756 state = SHIFTING_RIGHT;
dmartin99 12:f49bae848977 757 column_shifting = 0;
dmartin99 12:f49bae848977 758 }
dmartin99 12:f49bae848977 759 row_shifting = 0;
dmartin99 12:f49bae848977 760 aliens_y += 2;
dmartin99 12:f49bae848977 761 } else {
dmartin99 12:f49bae848977 762 row_shifting += 1;
dmartin99 12:f49bae848977 763 column_shifting = 0;
dmartin99 12:f49bae848977 764 }
dmartin99 12:f49bae848977 765 }
dmartin99 12:f49bae848977 766 break;
dmartin99 12:f49bae848977 767 }
dmartin99 12:f49bae848977 768 }
dmartin99 12:f49bae848977 769 };
dmartin99 12:f49bae848977 770
dmartin99 12:f49bae848977 771 class BulletUpdate {
dmartin99 12:f49bae848977 772 public:
dmartin99 12:f49bae848977 773 void operator()() {
dmartin99 12:f49bae848977 774 // Sample input devices
dmartin99 12:f49bae848977 775 bool fire_button_pressed_ = fire_button_pressed;
dmartin99 12:f49bae848977 776 fire_button_pressed = false;
dmartin99 12:f49bae848977 777
dmartin99 12:f49bae848977 778 bool fire_button_pressed_2 = fire_button_pressed2;
dmartin99 12:f49bae848977 779 fire_button_pressed2 = false;
dmartin99 12:f49bae848977 780
dmartin99 12:f49bae848977 781 // Update player bullet
dmartin99 12:f49bae848977 782 if (player_bullet_exists) {
dmartin99 12:f49bae848977 783 draw_bullet(player_bullet_x, player_bullet_y, BLACK);
dmartin99 12:f49bae848977 784 player_bullet_y -= 2;
dmartin99 12:f49bae848977 785 if (player_bullet_y < 0) {
dmartin99 12:f49bae848977 786 player_bullet_exists = false;
dmartin99 12:f49bae848977 787 }
dmartin99 12:f49bae848977 788 } else if (fire_button_pressed_) {
dmartin99 12:f49bae848977 789 add_audio(1);
dmartin99 12:f49bae848977 790 player_bullet_exists = true;
dmartin99 12:f49bae848977 791 player_bullet_x = player_x;
dmartin99 12:f49bae848977 792 player_bullet_y = SCREEN_MAX_Y - (SHIP_HEIGHT + SHIP_GUN_HEIGHT) - BULLET_HEIGHT - 1;
dmartin99 12:f49bae848977 793 }
dmartin99 12:f49bae848977 794
dmartin99 12:f49bae848977 795 if (player_bullet_exists) {
dmartin99 12:f49bae848977 796 if (barricade_exist_at(player_bullet_x, player_bullet_y)) {
dmartin99 12:f49bae848977 797 barricade_impact(player_bullet_x, player_bullet_y);
dmartin99 12:f49bae848977 798 player_bullet_exists = false;
dmartin99 12:f49bae848977 799 } else if (alien_impact(player_bullet_x, player_bullet_y)) {
dmartin99 12:f49bae848977 800 player_bullet_exists = false;
dmartin99 12:f49bae848977 801 } else if (pvp_state != -1 && player_impact(player_bullet_x, player_bullet_y + BULLET_HEIGHT)) {
dmartin99 12:f49bae848977 802 pvp_state = 1;
dmartin99 12:f49bae848977 803 }else {
dmartin99 12:f49bae848977 804 draw_bullet(player_bullet_x, player_bullet_y, BULLET_COLOR);
dmartin99 12:f49bae848977 805 }
dmartin99 12:f49bae848977 806 }
dmartin99 12:f49bae848977 807
dmartin99 12:f49bae848977 808 // Update player2 bullet
dmartin99 12:f49bae848977 809 if (player_bullet_exists2) {
dmartin99 12:f49bae848977 810 draw_bullet(player_bullet_x2, player_bullet_y2, BLACK);
dmartin99 12:f49bae848977 811 player_bullet_y2 -= pvp_state == -1 ? 2 : -2;
dmartin99 12:f49bae848977 812 if (player_bullet_y2 < 0 || player_bullet_y2 >= SCREEN_MAX_Y) {
dmartin99 12:f49bae848977 813 player_bullet_exists2 = false;
dmartin99 12:f49bae848977 814 }
dmartin99 12:f49bae848977 815 } else if (fire_button_pressed_2) {
dmartin99 12:f49bae848977 816 add_audio(1);
dmartin99 12:f49bae848977 817 player_bullet_exists2 = true;
dmartin99 12:f49bae848977 818 player_bullet_x2 = player_x2;
dmartin99 12:f49bae848977 819 if (pvp_state != -1)
dmartin99 12:f49bae848977 820 player_bullet_y2 = 0 + (SHIP_HEIGHT + SHIP_GUN_HEIGHT) + BULLET_HEIGHT + 1;
dmartin99 12:f49bae848977 821 else
dmartin99 12:f49bae848977 822 player_bullet_y2 = SCREEN_MAX_Y - (SHIP_HEIGHT + SHIP_GUN_HEIGHT) - BULLET_HEIGHT - 1;
dmartin99 12:f49bae848977 823 }
dmartin99 12:f49bae848977 824
dmartin99 12:f49bae848977 825 if (player_bullet_exists2) {
dmartin99 12:f49bae848977 826 if (barricade_exist_at(player_bullet_x2, player_bullet_y2)) {
dmartin99 12:f49bae848977 827 barricade_impact(player_bullet_x2, player_bullet_y2);
dmartin99 12:f49bae848977 828 player_bullet_exists2 = false;
dmartin99 12:f49bae848977 829 } else if (alien_impact(player_bullet_x2, player_bullet_y2)) {
dmartin99 12:f49bae848977 830 player_bullet_exists2 = false;
dmartin99 12:f49bae848977 831 } else if (pvp_state != -1 && player_impact(player_bullet_x2, player_bullet_y2 + BULLET_HEIGHT)) {
dmartin99 12:f49bae848977 832 pvp_state = 2;
dmartin99 12:f49bae848977 833 }else {
dmartin99 12:f49bae848977 834 draw_bullet(player_bullet_x2, player_bullet_y2, BULLET_COLOR);
dmartin99 12:f49bae848977 835 }
dmartin99 12:f49bae848977 836 }
dmartin99 12:f49bae848977 837
dmartin99 12:f49bae848977 838 if (pvp_state != -1)
dmartin99 12:f49bae848977 839 return;
dmartin99 12:f49bae848977 840
dmartin99 12:f49bae848977 841 // Update alien bullets
dmartin99 12:f49bae848977 842 for (int i = 0; i < 3; i++) {
dmartin99 12:f49bae848977 843 bool alien_fire_button_pressed = rand() % 64 == 0;
dmartin99 12:f49bae848977 844
dmartin99 12:f49bae848977 845 if (alien_bullets[i].exists) {
dmartin99 12:f49bae848977 846 draw_bullet(alien_bullets[i].x, alien_bullets[i].y, BLACK);
dmartin99 12:f49bae848977 847 alien_bullets[i].y += 2;
dmartin99 12:f49bae848977 848 if (alien_bullets[i].y >= SCREEN_MAX_Y) {
dmartin99 12:f49bae848977 849 alien_bullets[i].exists = false;
dmartin99 12:f49bae848977 850 }
dmartin99 12:f49bae848977 851 } else if (alien_fire_button_pressed) {
dmartin99 12:f49bae848977 852 int column_firing = rand() % 5;
dmartin99 12:f49bae848977 853 int row_firing = -1;
dmartin99 12:f49bae848977 854
dmartin99 12:f49bae848977 855 for (int y = 0; y < 5; y++) {
dmartin99 12:f49bae848977 856 if (aliens[column_firing][y]) {
dmartin99 12:f49bae848977 857 row_firing = y;
dmartin99 12:f49bae848977 858 }
dmartin99 12:f49bae848977 859 }
dmartin99 12:f49bae848977 860
dmartin99 12:f49bae848977 861 if (row_firing != -1) {
dmartin99 12:f49bae848977 862 alien_bullets[i].exists = true;
dmartin99 12:f49bae848977 863 alien_bullets[i].x = aliens_x + column_firing * 16 + (ALIEN_WIDTH / 2);
dmartin99 12:f49bae848977 864 alien_bullets[i].y = aliens_y + row_firing * 12 + ALIEN_HEIGHT + 1;
dmartin99 12:f49bae848977 865 }
dmartin99 12:f49bae848977 866 }
dmartin99 12:f49bae848977 867
dmartin99 12:f49bae848977 868 if (alien_bullets[i].exists) {
dmartin99 12:f49bae848977 869 if (barricade_exist_at(alien_bullets[i].x, alien_bullets[i].y + BULLET_HEIGHT)) {
dmartin99 12:f49bae848977 870 barricade_impact(alien_bullets[i].x, alien_bullets[i].y + BULLET_HEIGHT);
dmartin99 12:f49bae848977 871 alien_bullets[i].exists = false;
dmartin99 12:f49bae848977 872 } else if (player_impact(alien_bullets[i].x, alien_bullets[i].y + BULLET_HEIGHT)) {
dmartin99 12:f49bae848977 873 alien_bullets[i].exists = false;
dmartin99 12:f49bae848977 874 } else {
dmartin99 12:f49bae848977 875 draw_bullet(alien_bullets[i].x, alien_bullets[i].y, BULLET_COLOR);
dmartin99 12:f49bae848977 876 }
dmartin99 12:f49bae848977 877 }
dmartin99 12:f49bae848977 878 }
dmartin99 12:f49bae848977 879 }
dmartin99 12:f49bae848977 880 };
dmartin99 12:f49bae848977 881
dmartin99 12:f49bae848977 882 PlayerUpdate player_updater;
dmartin99 12:f49bae848977 883 PlayerUpdate2 player_updater2;
dmartin99 12:f49bae848977 884 AlienUpdate alien_updater;
dmartin99 12:f49bae848977 885 BulletUpdate bullet_updater;
dmartin99 12:f49bae848977 886 void game_loop() {
dmartin99 12:f49bae848977 887 player_updater();
dmartin99 12:f49bae848977 888 player_updater2();
dmartin99 12:f49bae848977 889
dmartin99 12:f49bae848977 890 alien_updater();
dmartin99 12:f49bae848977 891 bullet_updater();
dmartin99 12:f49bae848977 892
dmartin99 12:f49bae848977 893 // Seed random number generator if unseeded
dmartin99 12:f49bae848977 894 // Basically, we count the number of cycles until a fire button is pressed.
dmartin99 12:f49bae848977 895 // This should be sufficiently random, for game purposes at least.
dmartin99 12:f49bae848977 896 if (!random_seeded) {
dmartin99 12:f49bae848977 897 if (fire_button_pressed) {
dmartin99 12:f49bae848977 898 srand(random_seed);
dmartin99 12:f49bae848977 899 random_seeded = true;
dmartin99 12:f49bae848977 900 } else {
dmartin99 12:f49bae848977 901 random_seed += 1;
dmartin99 12:f49bae848977 902 }
dmartin99 12:f49bae848977 903 }
dmartin99 12:f49bae848977 904
dmartin99 12:f49bae848977 905 uLCD.text_height(1);
dmartin99 12:f49bae848977 906 uLCD.text_width(1);
dmartin99 12:f49bae848977 907 uLCD.locate(0, 0);
dmartin99 12:f49bae848977 908 uLCD.printf("Score:%i", player_score);
dmartin99 12:f49bae848977 909
dmartin99 12:f49bae848977 910 uLCD.locate(10, 0);
dmartin99 12:f49bae848977 911 uLCD.printf("Lives:%i", player_lives);
dmartin99 12:f49bae848977 912
dmartin99 12:f49bae848977 913 // Check for lose condition
dmartin99 12:f49bae848977 914 if (player_lives < 0) {
dmartin99 12:f49bae848977 915 uLCD.filled_rectangle(0, 0, SCREEN_MAX_X, BARRICADES_START_Y, BLACK);
dmartin99 12:f49bae848977 916
dmartin99 12:f49bae848977 917 uLCD.locate(0, 5);
dmartin99 12:f49bae848977 918 uLCD.printf(" Game Over\n");
dmartin99 12:f49bae848977 919 uLCD.printf(" Score: %5d\n", player_score);
dmartin99 12:f49bae848977 920 uLCD.printf("\n");
dmartin99 12:f49bae848977 921 uLCD.printf(" Press fire to\n");
dmartin99 12:f49bae848977 922 uLCD.printf(" play again.\n");
dmartin99 12:f49bae848977 923
dmartin99 12:f49bae848977 924 wait(0.6);
dmartin99 12:f49bae848977 925 add_audio(3);
dmartin99 12:f49bae848977 926
dmartin99 12:f49bae848977 927 wait(0.25);
dmartin99 12:f49bae848977 928 while (!(fire_button_pressed || fire_button_pressed2));
dmartin99 12:f49bae848977 929 wait(0.25);
dmartin99 12:f49bae848977 930 uLCD.cls();
dmartin99 12:f49bae848977 931 fire_button_pressed = false;
dmartin99 12:f49bae848977 932 fire_button_pressed2 = false;
dmartin99 12:f49bae848977 933 player_updater = PlayerUpdate();
dmartin99 12:f49bae848977 934 player_updater2 = PlayerUpdate2();
dmartin99 12:f49bae848977 935 alien_updater = AlienUpdate();
dmartin99 12:f49bae848977 936 bullet_updater = BulletUpdate();
dmartin99 12:f49bae848977 937 initialize_game_state();
dmartin99 12:f49bae848977 938 return;
dmartin99 12:f49bae848977 939 }
dmartin99 12:f49bae848977 940
dmartin99 12:f49bae848977 941 // Check for win condition
dmartin99 12:f49bae848977 942 bool all_aliens_destroyed = true;
dmartin99 12:f49bae848977 943 for (int x = 0; x < 5; x++) {
dmartin99 12:f49bae848977 944 for (int y = 0; y < 5; y++) {
dmartin99 12:f49bae848977 945 if (aliens[x][y]) {
dmartin99 12:f49bae848977 946 all_aliens_destroyed = false;
dmartin99 12:f49bae848977 947 break;
dmartin99 12:f49bae848977 948 }
dmartin99 12:f49bae848977 949 }
dmartin99 12:f49bae848977 950 }
dmartin99 12:f49bae848977 951
dmartin99 12:f49bae848977 952 if (all_aliens_destroyed) {
dmartin99 12:f49bae848977 953 uLCD.filled_rectangle(0, 0, SCREEN_MAX_X, BARRICADES_START_Y, BLACK);
dmartin99 12:f49bae848977 954
dmartin99 12:f49bae848977 955 uLCD.locate(0, 5);
dmartin99 12:f49bae848977 956 uLCD.printf(" You Win!\n");
dmartin99 12:f49bae848977 957 uLCD.printf(" Score: %5d\n", player_score);
dmartin99 12:f49bae848977 958 uLCD.printf("\n");
dmartin99 12:f49bae848977 959 uLCD.printf(" Press fire to\n");
dmartin99 12:f49bae848977 960 uLCD.printf(" play again.\n");
dmartin99 12:f49bae848977 961
dmartin99 12:f49bae848977 962
dmartin99 12:f49bae848977 963 wait(0.25);
dmartin99 12:f49bae848977 964 while (!(fire_button_pressed || fire_button_pressed2) );
dmartin99 12:f49bae848977 965 wait(0.25);
dmartin99 12:f49bae848977 966 uLCD.cls();
dmartin99 12:f49bae848977 967 fire_button_pressed = false;
dmartin99 12:f49bae848977 968 fire_button_pressed2 = false;
dmartin99 12:f49bae848977 969 player_updater = PlayerUpdate();
dmartin99 12:f49bae848977 970 player_updater2 = PlayerUpdate2();
dmartin99 12:f49bae848977 971 alien_updater = AlienUpdate();
dmartin99 12:f49bae848977 972 bullet_updater = BulletUpdate();
dmartin99 12:f49bae848977 973 initialize_game_state();
dmartin99 12:f49bae848977 974 return;
dmartin99 12:f49bae848977 975 }
dmartin99 12:f49bae848977 976 }
dmartin99 12:f49bae848977 977
dmartin99 12:f49bae848977 978 void game_loop2() {
dmartin99 12:f49bae848977 979 player_updater.alien();
dmartin99 12:f49bae848977 980 player_updater2.alien();
dmartin99 12:f49bae848977 981
dmartin99 12:f49bae848977 982 bullet_updater();
dmartin99 12:f49bae848977 983
dmartin99 12:f49bae848977 984 // Check for lose condition
dmartin99 12:f49bae848977 985 if (pvp_state != 0) {
dmartin99 12:f49bae848977 986 uLCD.filled_rectangle(0, 0, SCREEN_MAX_X, BARRICADES_START_Y, BLACK);
dmartin99 12:f49bae848977 987
dmartin99 12:f49bae848977 988 uLCD.locate(0, 5);
dmartin99 12:f49bae848977 989 uLCD.printf(" Game Over\n");
dmartin99 12:f49bae848977 990 uLCD.printf(" Player %i won", pvp_state);
dmartin99 12:f49bae848977 991 uLCD.printf("\n");
dmartin99 12:f49bae848977 992 uLCD.printf(" Press fire to\n");
dmartin99 12:f49bae848977 993 uLCD.printf(" play again.\n");
dmartin99 12:f49bae848977 994 wait(0.6);
dmartin99 12:f49bae848977 995 add_audio(3);
dmartin99 12:f49bae848977 996
dmartin99 12:f49bae848977 997 wait(0.25);
dmartin99 12:f49bae848977 998 while (!(fire_button_pressed || fire_button_pressed2));
dmartin99 12:f49bae848977 999 wait(0.25);
dmartin99 12:f49bae848977 1000 uLCD.cls();
dmartin99 12:f49bae848977 1001 fire_button_pressed = false;
dmartin99 12:f49bae848977 1002 fire_button_pressed2 = false;
dmartin99 12:f49bae848977 1003 player_bullet_exists = false;
dmartin99 12:f49bae848977 1004 player_bullet_exists2 = false;
dmartin99 12:f49bae848977 1005 initialize_game_state2();
dmartin99 12:f49bae848977 1006 pvp_state = 0;
dmartin99 12:f49bae848977 1007 }
dmartin99 12:f49bae848977 1008 }
dmartin99 12:f49bae848977 1009
dmartin99 12:f49bae848977 1010
emilmont 1:491820ee784d 1011 int main() {
dmartin99 12:f49bae848977 1012 initialize_devices();
dmartin99 12:f49bae848977 1013 dev.attach(&dev_recv, Serial::RxIrq);
dmartin99 12:f49bae848977 1014
dmartin99 12:f49bae848977 1015 uLCD.locate(0, 5);
dmartin99 12:f49bae848977 1016 uLCD.printf(" Please Connect\n");
dmartin99 12:f49bae848977 1017 uLCD.printf(" Both Devices!\n");
dmartin99 12:f49bae848977 1018
dmartin99 12:f49bae848977 1019 uLCD.locate(0, 8);
dmartin99 12:f49bae848977 1020 uLCD.printf("Player 1:Not Ready");
dmartin99 12:f49bae848977 1021
dmartin99 12:f49bae848977 1022 uLCD.locate(0, 9);
dmartin99 12:f49bae848977 1023 uLCD.printf("Player 2:Not Ready");
dmartin99 12:f49bae848977 1024
dmartin99 12:f49bae848977 1025 while (!(player_alive && player_alive2)) {
dmartin99 12:f49bae848977 1026 if (player_alive) {
dmartin99 12:f49bae848977 1027 uLCD.locate(0, 8);
dmartin99 12:f49bae848977 1028 uLCD.printf("Player 1:Ready ");
dmartin99 12:f49bae848977 1029 }
dmartin99 12:f49bae848977 1030
dmartin99 12:f49bae848977 1031 if (player_alive2) {
dmartin99 12:f49bae848977 1032 uLCD.locate(0, 9);
dmartin99 12:f49bae848977 1033 uLCD.printf("Player 2:Ready ");
dmartin99 12:f49bae848977 1034 }
dmartin99 12:f49bae848977 1035 wait(0.01);
dmartin99 12:f49bae848977 1036 }
dmartin99 12:f49bae848977 1037 fire_button_pressed = false;
dmartin99 12:f49bae848977 1038 fire_button_pressed2 = false;
dmartin99 12:f49bae848977 1039
dmartin99 12:f49bae848977 1040 uLCD.cls();
dmartin99 12:f49bae848977 1041
dmartin99 12:f49bae848977 1042 uLCD.locate(0, 5);
dmartin99 12:f49bae848977 1043 uLCD.printf(" Select Mode!\n");
dmartin99 12:f49bae848977 1044
dmartin99 12:f49bae848977 1045 uLCD.locate(0, 8);
dmartin99 12:f49bae848977 1046 uLCD.printf("Normal -Seleted");
dmartin99 12:f49bae848977 1047
dmartin99 12:f49bae848977 1048 uLCD.locate(0, 9);
dmartin99 12:f49bae848977 1049 uLCD.printf("PVP ");
dmartin99 12:f49bae848977 1050
dmartin99 12:f49bae848977 1051 while (!(fire_button_pressed)) {
dmartin99 12:f49bae848977 1052 if (vertical_movement > 0.1) {
dmartin99 12:f49bae848977 1053 uLCD.locate(0, 8);
dmartin99 12:f49bae848977 1054 uLCD.printf("Normal ");
dmartin99 12:f49bae848977 1055 uLCD.locate(0, 9);
dmartin99 12:f49bae848977 1056 uLCD.printf("PVP -Seleted");
dmartin99 12:f49bae848977 1057 pvp_state = 0;
dmartin99 12:f49bae848977 1058 }else if (vertical_movement < 0.1) {
dmartin99 12:f49bae848977 1059 uLCD.locate(0, 8);
dmartin99 12:f49bae848977 1060 uLCD.printf("Normal -Seleted");
dmartin99 12:f49bae848977 1061 uLCD.locate(0, 9);
dmartin99 12:f49bae848977 1062 uLCD.printf("PVP ");
dmartin99 12:f49bae848977 1063 pvp_state = -1;
dmartin99 12:f49bae848977 1064 }
dmartin99 12:f49bae848977 1065 vertical_movement = 0;
dmartin99 12:f49bae848977 1066 wait(0.01);
dmartin99 12:f49bae848977 1067 }
dmartin99 12:f49bae848977 1068 fire_button_pressed = false;
dmartin99 12:f49bae848977 1069 fire_button_pressed2 = false;
dmartin99 12:f49bae848977 1070
dmartin99 12:f49bae848977 1071 uLCD.cls();
dmartin99 12:f49bae848977 1072
dmartin99 12:f49bae848977 1073 if (pvp_state != -1)
dmartin99 12:f49bae848977 1074 initialize_game_state2();
dmartin99 12:f49bae848977 1075 else
dmartin99 12:f49bae848977 1076 initialize_game_state();
dmartin99 12:f49bae848977 1077
dmartin99 12:f49bae848977 1078 audio_thread.start(audio_thread_run);
emilmont 1:491820ee784d 1079
emilmont 1:491820ee784d 1080 while (true) {
dmartin99 12:f49bae848977 1081 if (pvp_state != -1)
dmartin99 12:f49bae848977 1082 game_loop2();
dmartin99 12:f49bae848977 1083 else
dmartin99 12:f49bae848977 1084 game_loop();
dmartin99 12:f49bae848977 1085 wait(0.005);
emilmont 1:491820ee784d 1086 }
dmartin99 12:f49bae848977 1087 }