
Final Submission. I have read and agreed with Statement of Academic Integrity.
Dependencies: mbed
main.cpp@2:bb50c3a9a05c, 2020-05-22 (annotated)
- Committer:
- Nicholas75179
- Date:
- Fri May 22 10:28:29 2020 +0000
- Revision:
- 2:bb50c3a9a05c
- Parent:
- 1:3727d33a171b
published 11:27 22/5/2020
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Nicholas75179 | 1:3727d33a171b | 1 | /* |
Nicholas75179 | 1:3727d33a171b | 2 | ELEC2645 Embedded Systems Project |
Nicholas75179 | 1:3727d33a171b | 3 | School of Electronic & Electrical Engineering |
Nicholas75179 | 1:3727d33a171b | 4 | University of Leeds |
Nicholas75179 | 1:3727d33a171b | 5 | Name: Nicholas Wu |
Nicholas75179 | 1:3727d33a171b | 6 | Username: el18nw |
Nicholas75179 | 1:3727d33a171b | 7 | Student ID Number: 201275179 |
Nicholas75179 | 1:3727d33a171b | 8 | Date: 22/5/2020 |
Nicholas75179 | 1:3727d33a171b | 9 | */ |
Nicholas75179 | 0:fde420d18f42 | 10 | |
Nicholas75179 | 0:fde420d18f42 | 11 | #include "mbed.h" |
Nicholas75179 | 0:fde420d18f42 | 12 | #include "Gamepad.h" |
Nicholas75179 | 0:fde420d18f42 | 13 | #include "N5110.h" |
Nicholas75179 | 0:fde420d18f42 | 14 | #include "Bitmap.h" |
Nicholas75179 | 0:fde420d18f42 | 15 | #include "Spaceship.h" |
Nicholas75179 | 0:fde420d18f42 | 16 | |
Nicholas75179 | 0:fde420d18f42 | 17 | // IN-GAME DEBUGGING FLAGS |
Nicholas75179 | 0:fde420d18f42 | 18 | bool DEBUG_menu = 0; |
Nicholas75179 | 0:fde420d18f42 | 19 | bool sound_on = 1; |
Nicholas75179 | 0:fde420d18f42 | 20 | // During development a mixture of serial port and in-game debugging methods |
Nicholas75179 | 0:fde420d18f42 | 21 | // I found in-game debugging to be more interesting and accessible |
Nicholas75179 | 0:fde420d18f42 | 22 | // Thus I had left these two debugging options here as examples |
Nicholas75179 | 0:fde420d18f42 | 23 | |
Nicholas75179 | 0:fde420d18f42 | 24 | // OBJECTS |
Nicholas75179 | 0:fde420d18f42 | 25 | Gamepad pad; |
Nicholas75179 | 0:fde420d18f42 | 26 | N5110 lcd; |
Nicholas75179 | 0:fde420d18f42 | 27 | Bitmap AGALAG(title, 10, 48); // name, y and x width |
Nicholas75179 | 0:fde420d18f42 | 28 | Bitmap SHIP0(player_ship0, 9, 12); |
Nicholas75179 | 0:fde420d18f42 | 29 | Bitmap SHIP1(player_ship1, 9, 12); |
Nicholas75179 | 0:fde420d18f42 | 30 | Spaceship player; |
Nicholas75179 | 0:fde420d18f42 | 31 | Spaceship enemy[2]; |
Nicholas75179 | 0:fde420d18f42 | 32 | // Declaring enemies as an array makes adding more enemies simple |
Nicholas75179 | 0:fde420d18f42 | 33 | // for this platform 2 allows for a playable framerate |
Nicholas75179 | 0:fde420d18f42 | 34 | |
Nicholas75179 | 0:fde420d18f42 | 35 | // FUNCTIONS & RESPECTIVE VARIABLES |
Nicholas75179 | 0:fde420d18f42 | 36 | void dramatic_print(string, int, int, int); |
Nicholas75179 | 0:fde420d18f42 | 37 | int temptime = clock(); |
Nicholas75179 | 0:fde420d18f42 | 38 | char g_buffer[14] = "0"; |
Nicholas75179 | 0:fde420d18f42 | 39 | void title_sequence(); |
Nicholas75179 | 0:fde420d18f42 | 40 | float g_x = 0, g_y = 0; |
Nicholas75179 | 0:fde420d18f42 | 41 | void create_stars(); |
Nicholas75179 | 0:fde420d18f42 | 42 | bool g_star_map[224][224]; |
Nicholas75179 | 0:fde420d18f42 | 43 | bool check_stars(int, int); |
Nicholas75179 | 0:fde420d18f42 | 44 | void print_background(float, float, float); |
Nicholas75179 | 0:fde420d18f42 | 45 | void menu(); |
Nicholas75179 | 0:fde420d18f42 | 46 | void help(); |
Nicholas75179 | 0:fde420d18f42 | 47 | void ship_select(); |
Nicholas75179 | 0:fde420d18f42 | 48 | int player_ship_type = 0; |
Nicholas75179 | 0:fde420d18f42 | 49 | bool difficulty = 0; |
Nicholas75179 | 0:fde420d18f42 | 50 | bool god_mode = 0; |
Nicholas75179 | 0:fde420d18f42 | 51 | void print_menu(int, int); |
Nicholas75179 | 0:fde420d18f42 | 52 | void level_system(); |
Nicholas75179 | 0:fde420d18f42 | 53 | int points = 0; |
Nicholas75179 | 0:fde420d18f42 | 54 | void engine_setup(bool); |
Nicholas75179 | 0:fde420d18f42 | 55 | void engine(bool, float); |
Nicholas75179 | 0:fde420d18f42 | 56 | void render_objects(int); |
Nicholas75179 | 0:fde420d18f42 | 57 | void draw_enemy(int, int, int); |
Nicholas75179 | 0:fde420d18f42 | 58 | void effects(bool, int, float); |
Nicholas75179 | 0:fde420d18f42 | 59 | void sound(bool); |
Nicholas75179 | 0:fde420d18f42 | 60 | bool explode(int, int); |
Nicholas75179 | 0:fde420d18f42 | 61 | void print_tracker(int i); |
Nicholas75179 | 0:fde420d18f42 | 62 | |
Nicholas75179 | 0:fde420d18f42 | 63 | int main() { |
Nicholas75179 | 0:fde420d18f42 | 64 | lcd.init(); |
Nicholas75179 | 0:fde420d18f42 | 65 | lcd.inverseMode(); |
Nicholas75179 | 0:fde420d18f42 | 66 | lcd.setContrast(0.48); |
Nicholas75179 | 0:fde420d18f42 | 67 | pad.init(); |
Nicholas75179 | 0:fde420d18f42 | 68 | lcd.backLightOn(); |
Nicholas75179 | 0:fde420d18f42 | 69 | create_stars(); |
Nicholas75179 | 0:fde420d18f42 | 70 | title_sequence(); |
Nicholas75179 | 0:fde420d18f42 | 71 | while (1) menu(); |
Nicholas75179 | 0:fde420d18f42 | 72 | } |
Nicholas75179 | 0:fde420d18f42 | 73 | |
Nicholas75179 | 0:fde420d18f42 | 74 | void menu() { |
Nicholas75179 | 0:fde420d18f42 | 75 | int menu = 0, selection = 0; |
Nicholas75179 | 0:fde420d18f42 | 76 | |
Nicholas75179 | 0:fde420d18f42 | 77 | while (1) { |
Nicholas75179 | 0:fde420d18f42 | 78 | lcd.clear(); |
Nicholas75179 | 0:fde420d18f42 | 79 | print_background(1, 0, 0); |
Nicholas75179 | 0:fde420d18f42 | 80 | print_menu(menu, selection); |
Nicholas75179 | 0:fde420d18f42 | 81 | AGALAG.render(lcd, 18, 5); |
Nicholas75179 | 0:fde420d18f42 | 82 | |
Nicholas75179 | 0:fde420d18f42 | 83 | if (pad.B_held()) selection++; |
Nicholas75179 | 0:fde420d18f42 | 84 | if (pad.X_held()) selection--; |
Nicholas75179 | 0:fde420d18f42 | 85 | while (pad.B_held() || pad.X_held()); |
Nicholas75179 | 0:fde420d18f42 | 86 | if (selection < 0) selection = 3; |
Nicholas75179 | 0:fde420d18f42 | 87 | else if (selection > 3) selection = 0; |
Nicholas75179 | 0:fde420d18f42 | 88 | if (DEBUG_menu) { |
Nicholas75179 | 0:fde420d18f42 | 89 | sprintf(g_buffer, " %1i,%1i", menu, selection); |
Nicholas75179 | 0:fde420d18f42 | 90 | lcd.printString(g_buffer, 0, 5); |
Nicholas75179 | 0:fde420d18f42 | 91 | } |
Nicholas75179 | 0:fde420d18f42 | 92 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 93 | |
Nicholas75179 | 0:fde420d18f42 | 94 | if (pad.A_held() || pad.Y_held()) { |
Nicholas75179 | 0:fde420d18f42 | 95 | if (menu == 3) { |
Nicholas75179 | 0:fde420d18f42 | 96 | if (selection == 0) sound_on = !sound_on; |
Nicholas75179 | 0:fde420d18f42 | 97 | if (selection == 1) points += 100;; |
Nicholas75179 | 0:fde420d18f42 | 98 | if (selection == 2) DEBUG_menu = !DEBUG_menu; |
Nicholas75179 | 0:fde420d18f42 | 99 | if (selection == 3) menu = 0; |
Nicholas75179 | 0:fde420d18f42 | 100 | }else if (menu==1) { |
Nicholas75179 | 0:fde420d18f42 | 101 | if (selection == 0) ship_select(); |
Nicholas75179 | 0:fde420d18f42 | 102 | if (selection == 1) god_mode =! god_mode; |
Nicholas75179 | 0:fde420d18f42 | 103 | if (selection == 2) difficulty =! difficulty; |
Nicholas75179 | 0:fde420d18f42 | 104 | if (selection == 3) menu = 0; |
Nicholas75179 | 0:fde420d18f42 | 105 | }else if (menu == 0) { |
Nicholas75179 | 0:fde420d18f42 | 106 | if (selection == 0) level_system(); |
Nicholas75179 | 0:fde420d18f42 | 107 | if (selection == 1) menu = 1; |
Nicholas75179 | 0:fde420d18f42 | 108 | if (selection == 2) help(); |
Nicholas75179 | 0:fde420d18f42 | 109 | if (selection == 3) menu = 3; |
Nicholas75179 | 0:fde420d18f42 | 110 | } |
Nicholas75179 | 0:fde420d18f42 | 111 | //this while statement captures the frame so no more than |
Nicholas75179 | 0:fde420d18f42 | 112 | //one increment could happen with each button press |
Nicholas75179 | 0:fde420d18f42 | 113 | while (pad.A_held() || pad.Y_held()); |
Nicholas75179 | 0:fde420d18f42 | 114 | } |
Nicholas75179 | 0:fde420d18f42 | 115 | } |
Nicholas75179 | 0:fde420d18f42 | 116 | } |
Nicholas75179 | 0:fde420d18f42 | 117 | |
Nicholas75179 | 0:fde420d18f42 | 118 | void print_menu(int menu, int selection) { |
Nicholas75179 | 0:fde420d18f42 | 119 | //selected menu item is denoted as such: >example< |
Nicholas75179 | 0:fde420d18f42 | 120 | if (menu == 0) { |
Nicholas75179 | 0:fde420d18f42 | 121 | if (selection == 0) lcd.printString(">PLAY!<", 21, 2); |
Nicholas75179 | 0:fde420d18f42 | 122 | else lcd.printString("PLAY!", 27, 2); |
Nicholas75179 | 0:fde420d18f42 | 123 | if (selection == 1) lcd.printString(">OPTIONS<", 15, 3); |
Nicholas75179 | 0:fde420d18f42 | 124 | else lcd.printString("OPTIONS", 21, 3); |
Nicholas75179 | 0:fde420d18f42 | 125 | if (selection == 2) lcd.printString(">CONTROLS<", 12, 4); |
Nicholas75179 | 0:fde420d18f42 | 126 | else lcd.printString("CONTROLS", 18, 4); |
Nicholas75179 | 0:fde420d18f42 | 127 | if (selection == 3) lcd.printString(">DEBUG<", 21, 5); |
Nicholas75179 | 0:fde420d18f42 | 128 | else lcd.printString("DEBUG", 27, 5); |
Nicholas75179 | 0:fde420d18f42 | 129 | } |
Nicholas75179 | 0:fde420d18f42 | 130 | if (menu == 1) { |
Nicholas75179 | 0:fde420d18f42 | 131 | if (selection == 0) lcd.printString(">SHIP=0<", 18, 2); |
Nicholas75179 | 0:fde420d18f42 | 132 | else lcd.printString("SHIP=0", 24, 2); |
Nicholas75179 | 0:fde420d18f42 | 133 | lcd.printChar(player_ship_type+49, 54, 2); |
Nicholas75179 | 0:fde420d18f42 | 134 | if (selection == 1) lcd.printString(">GOD MODE=0<", 6, 3); |
Nicholas75179 | 0:fde420d18f42 | 135 | else lcd.printString("GOD MODE=0", 12, 3); |
Nicholas75179 | 0:fde420d18f42 | 136 | lcd.printChar(48+god_mode, 66, 3); |
Nicholas75179 | 0:fde420d18f42 | 137 | if (selection == 2) lcd.printString(">EASY MODE<", 9, 4); |
Nicholas75179 | 0:fde420d18f42 | 138 | else lcd.printString("EASY MODE", 15, 4); |
Nicholas75179 | 0:fde420d18f42 | 139 | if (difficulty) lcd.printString("HARD", 15, 4); |
Nicholas75179 | 0:fde420d18f42 | 140 | if (selection == 3) lcd.printString(">BACK<", 24, 5); |
Nicholas75179 | 0:fde420d18f42 | 141 | else lcd.printString("BACK", 30, 5); |
Nicholas75179 | 0:fde420d18f42 | 142 | } |
Nicholas75179 | 0:fde420d18f42 | 143 | if (menu==3) { |
Nicholas75179 | 0:fde420d18f42 | 144 | if (selection == 0) lcd.printString(">SOUND=0<", 15, 2); |
Nicholas75179 | 0:fde420d18f42 | 145 | else lcd.printString("SOUND=0", 21, 2); |
Nicholas75179 | 0:fde420d18f42 | 146 | if (sound_on) lcd.printString("1", 57, 2); |
Nicholas75179 | 0:fde420d18f42 | 147 | if (selection == 1) lcd.printString(">POINTS= 0<", 3, 3); |
Nicholas75179 | 0:fde420d18f42 | 148 | else lcd.printString("POINTS= 0", 9, 3); |
Nicholas75179 | 0:fde420d18f42 | 149 | sprintf(g_buffer, "%4i", points); |
Nicholas75179 | 0:fde420d18f42 | 150 | lcd.printString(g_buffer, 52, 3); |
Nicholas75179 | 0:fde420d18f42 | 151 | if (selection == 2) lcd.printString(">MENU DB=0<", 9, 4); |
Nicholas75179 | 0:fde420d18f42 | 152 | else lcd.printString("MENU DB=0", 15, 4); |
Nicholas75179 | 0:fde420d18f42 | 153 | if (DEBUG_menu) lcd.printString("1", 63, 4); |
Nicholas75179 | 0:fde420d18f42 | 154 | if (selection == 3) lcd.printString(">BACK<", 24, 5); |
Nicholas75179 | 0:fde420d18f42 | 155 | else lcd.printString("BACK", 30, 5); |
Nicholas75179 | 0:fde420d18f42 | 156 | } |
Nicholas75179 | 0:fde420d18f42 | 157 | } |
Nicholas75179 | 0:fde420d18f42 | 158 | |
Nicholas75179 | 0:fde420d18f42 | 159 | void ship_select() { |
Nicholas75179 | 0:fde420d18f42 | 160 | player_ship_type++; |
Nicholas75179 | 0:fde420d18f42 | 161 | player_ship_type %= 2; |
Nicholas75179 | 0:fde420d18f42 | 162 | //selects between one of two |
Nicholas75179 | 0:fde420d18f42 | 163 | //ship types available |
Nicholas75179 | 0:fde420d18f42 | 164 | } |
Nicholas75179 | 0:fde420d18f42 | 165 | |
Nicholas75179 | 0:fde420d18f42 | 166 | void level_system() { |
Nicholas75179 | 0:fde420d18f42 | 167 | while (!pad.start_held()) { |
Nicholas75179 | 0:fde420d18f42 | 168 | create_stars(); |
Nicholas75179 | 0:fde420d18f42 | 169 | engine_setup(int(points/400)); |
Nicholas75179 | 0:fde420d18f42 | 170 | //passing the result of this division saves calculation during gameplay |
Nicholas75179 | 0:fde420d18f42 | 171 | if (enemy[0].HP <= 0 && enemy[1].HP <= 0 && player.HP <= 0) { |
Nicholas75179 | 0:fde420d18f42 | 172 | lcd.printString("<ACCEPTABLE>", 6, 4); |
Nicholas75179 | 0:fde420d18f42 | 173 | } |
Nicholas75179 | 0:fde420d18f42 | 174 | else if (player.HP <= 0) lcd.printString("<GAME OVER>", 9, 4); |
Nicholas75179 | 0:fde420d18f42 | 175 | else if (enemy[0].HP <= 0 && enemy[1].HP <= 0) { |
Nicholas75179 | 0:fde420d18f42 | 176 | lcd.printString("<NICE>", 24, 4); |
Nicholas75179 | 0:fde420d18f42 | 177 | points += 100; |
Nicholas75179 | 0:fde420d18f42 | 178 | if (difficulty) points += 100; |
Nicholas75179 | 0:fde420d18f42 | 179 | if (points>400) points += 100; |
Nicholas75179 | 0:fde420d18f42 | 180 | } else lcd.printString("<TOO SLOW>", 12, 4); |
Nicholas75179 | 0:fde420d18f42 | 181 | //above checks victory conditions, extra points for difficulty |
Nicholas75179 | 0:fde420d18f42 | 182 | sprintf(g_buffer, "SCORE:%4i", points); |
Nicholas75179 | 0:fde420d18f42 | 183 | if (enemy[0].HP > 0 || enemy[1].HP > 0) points = 0; |
Nicholas75179 | 0:fde420d18f42 | 184 | lcd.printString(g_buffer, 12, 5); |
Nicholas75179 | 0:fde420d18f42 | 185 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 186 | wait_ms(200); |
Nicholas75179 | 0:fde420d18f42 | 187 | if (points <= 200) lcd.printString("<EXIT: START>", 6, 0); |
Nicholas75179 | 0:fde420d18f42 | 188 | lcd.printString("<PLAY: ABXY>", 9, 1); |
Nicholas75179 | 0:fde420d18f42 | 189 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 190 | while (!pad.A_held() && !pad.B_held() && !pad.Y_held() |
Nicholas75179 | 0:fde420d18f42 | 191 | && !pad.X_held() && !pad.start_held()); |
Nicholas75179 | 0:fde420d18f42 | 192 | } |
Nicholas75179 | 0:fde420d18f42 | 193 | pad.leds(0); |
Nicholas75179 | 0:fde420d18f42 | 194 | } |
Nicholas75179 | 0:fde420d18f42 | 195 | |
Nicholas75179 | 0:fde420d18f42 | 196 | void engine_setup (bool phase_two) { |
Nicholas75179 | 0:fde420d18f42 | 197 | float HP_divider; |
Nicholas75179 | 0:fde420d18f42 | 198 | //init_ship sets parameters - position, direction, |
Nicholas75179 | 0:fde420d18f42 | 199 | //turn rate, acceleration, speed and hitpoints |
Nicholas75179 | 0:fde420d18f42 | 200 | if (player_ship_type == 0) { |
Nicholas75179 | 0:fde420d18f42 | 201 | player.init_ship(1, 0, 0, 0.05, 0.05, 0.7, 12); |
Nicholas75179 | 0:fde420d18f42 | 202 | HP_divider = 0.5; //HP divider is used to display health on the LEDs |
Nicholas75179 | 0:fde420d18f42 | 203 | } else { |
Nicholas75179 | 0:fde420d18f42 | 204 | player.init_ship(1, 0, 0, 0.15, 0.15, 0.5, 20); |
Nicholas75179 | 0:fde420d18f42 | 205 | HP_divider = 0.3; |
Nicholas75179 | 0:fde420d18f42 | 206 | } //ship type 2: slower speed and fire rate, |
Nicholas75179 | 0:fde420d18f42 | 207 | //faster turn rate, higher damage and more HP |
Nicholas75179 | 0:fde420d18f42 | 208 | enemy[0].init_ship(40, -20+rand()%40, -1+rand()%2, |
Nicholas75179 | 0:fde420d18f42 | 209 | 0.06+0.00005*points, 0.08+0.0001*points, 0.7+0.001*points, 10); |
Nicholas75179 | 0:fde420d18f42 | 210 | //additional maths in the enemy initialisation |
Nicholas75179 | 0:fde420d18f42 | 211 | //to increase difficulty over time |
Nicholas75179 | 0:fde420d18f42 | 212 | if (difficulty) for (int i = 0; i <= 1; i++) { |
Nicholas75179 | 0:fde420d18f42 | 213 | enemy[i].init_ship(50+rand()%30, 10-20*i, 2-4*i, |
Nicholas75179 | 0:fde420d18f42 | 214 | 0.06+0.00005*points, 0.1+0.0001*points, 1+0.001*points, 10); |
Nicholas75179 | 0:fde420d18f42 | 215 | } else if (phase_two) for (int i = 0; i <= 1; i++) { |
Nicholas75179 | 0:fde420d18f42 | 216 | enemy[i].init_ship(50+rand()%30, 10-20*i, -1+2*i, |
Nicholas75179 | 0:fde420d18f42 | 217 | 0.05+0.00005*points, 0.05+0.0001*points, 0.4+0.001*points, 10); |
Nicholas75179 | 0:fde420d18f42 | 218 | } |
Nicholas75179 | 0:fde420d18f42 | 219 | engine(phase_two, HP_divider); |
Nicholas75179 | 0:fde420d18f42 | 220 | } |
Nicholas75179 | 0:fde420d18f42 | 221 | |
Nicholas75179 | 0:fde420d18f42 | 222 | void engine(bool phase_two, float HP_divider) { |
Nicholas75179 | 0:fde420d18f42 | 223 | int end_delay = 40, time_limit = clock() + 6000; |
Nicholas75179 | 0:fde420d18f42 | 224 | // end_delay lets the animation continue for about two seconds after death |
Nicholas75179 | 0:fde420d18f42 | 225 | // time_limit keeps the game fun by forcing players to engage with the game |
Nicholas75179 | 0:fde420d18f42 | 226 | |
Nicholas75179 | 0:fde420d18f42 | 227 | while (end_delay > 0 && clock() < time_limit) { |
Nicholas75179 | 0:fde420d18f42 | 228 | Vector2D coord=pad.get_mapped_coord(); |
Nicholas75179 | 0:fde420d18f42 | 229 | lcd.clear(); |
Nicholas75179 | 0:fde420d18f42 | 230 | |
Nicholas75179 | 0:fde420d18f42 | 231 | for (int i = 0; i <= (difficulty || phase_two); i++) { |
Nicholas75179 | 0:fde420d18f42 | 232 | if (enemy[i].HP > 0) { |
Nicholas75179 | 0:fde420d18f42 | 233 | enemy[i].AI_controls(player.pos_x, player.pos_y, player.orientation); |
Nicholas75179 | 0:fde420d18f42 | 234 | } |
Nicholas75179 | 0:fde420d18f42 | 235 | if (enemy[i].check_hitbox(int(player.pos_x), int(player.pos_y), 4)) { |
Nicholas75179 | 0:fde420d18f42 | 236 | player.HP--; |
Nicholas75179 | 0:fde420d18f42 | 237 | } |
Nicholas75179 | 0:fde420d18f42 | 238 | if (player.check_hitbox(int(enemy[i].pos_x), int(enemy[i].pos_y), 5)) { |
Nicholas75179 | 0:fde420d18f42 | 239 | if (player_ship_type == 0)enemy[i].HP--; |
Nicholas75179 | 0:fde420d18f42 | 240 | else enemy[i].HP -= 4; //cannon on ship1 does more damage |
Nicholas75179 | 0:fde420d18f42 | 241 | } |
Nicholas75179 | 0:fde420d18f42 | 242 | enemy[i].update(); |
Nicholas75179 | 0:fde420d18f42 | 243 | }//change the for loop and object declaration to add more enemies |
Nicholas75179 | 0:fde420d18f42 | 244 | |
Nicholas75179 | 0:fde420d18f42 | 245 | if (player_ship_type == 0) SHIP0.render(lcd, 60, 20); |
Nicholas75179 | 0:fde420d18f42 | 246 | else SHIP1.render(lcd, 60, 20); |
Nicholas75179 | 0:fde420d18f42 | 247 | |
Nicholas75179 | 0:fde420d18f42 | 248 | render_objects(phase_two || difficulty); |
Nicholas75179 | 0:fde420d18f42 | 249 | effects(phase_two, time_limit, HP_divider); |
Nicholas75179 | 0:fde420d18f42 | 250 | // effects control every other aspect of the gamepad output |
Nicholas75179 | 0:fde420d18f42 | 251 | |
Nicholas75179 | 0:fde420d18f42 | 252 | if (player.HP > 0) { |
Nicholas75179 | 0:fde420d18f42 | 253 | player.controls(player_ship_type, pad.Y_held(), |
Nicholas75179 | 0:fde420d18f42 | 254 | pad.A_held(), pad.X_held(), pad.B_held(), coord.x, coord.y); |
Nicholas75179 | 0:fde420d18f42 | 255 | } |
Nicholas75179 | 0:fde420d18f42 | 256 | if ((enemy[0].HP<=0 && enemy[1].HP <= 0) || player.HP <= 0) end_delay--; |
Nicholas75179 | 0:fde420d18f42 | 257 | if (god_mode) player.HP = 24; |
Nicholas75179 | 0:fde420d18f42 | 258 | |
Nicholas75179 | 0:fde420d18f42 | 259 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 260 | // I opted not to limit the frame rate of the game because |
Nicholas75179 | 0:fde420d18f42 | 261 | // it will never render fast enough to be less fun |
Nicholas75179 | 0:fde420d18f42 | 262 | // as if it was running at full speed |
Nicholas75179 | 0:fde420d18f42 | 263 | } |
Nicholas75179 | 0:fde420d18f42 | 264 | } |
Nicholas75179 | 0:fde420d18f42 | 265 | |
Nicholas75179 | 0:fde420d18f42 | 266 | void render_objects(int extra_enemies) { |
Nicholas75179 | 0:fde420d18f42 | 267 | int temp1, temp2; |
Nicholas75179 | 0:fde420d18f42 | 268 | float sine = sin(player.orientation), cosine = cos(player.orientation); |
Nicholas75179 | 0:fde420d18f42 | 269 | |
Nicholas75179 | 0:fde420d18f42 | 270 | for (int i = -16; i < 69; i++) { |
Nicholas75179 | 0:fde420d18f42 | 271 | for (int ii = -24; ii < 32; ii++) { |
Nicholas75179 | 0:fde420d18f42 | 272 | temp1 = int(player.pos_x + (i * cosine - ii * sine)); |
Nicholas75179 | 0:fde420d18f42 | 273 | temp2 = int(player.pos_y + (ii * cosine + i * sine)); |
Nicholas75179 | 0:fde420d18f42 | 274 | |
Nicholas75179 | 0:fde420d18f42 | 275 | if (temp1 == int(enemy[0].pos_x) |
Nicholas75179 | 0:fde420d18f42 | 276 | && temp2 == int(enemy[0].pos_y)) { |
Nicholas75179 | 0:fde420d18f42 | 277 | draw_enemy(i, ii, 0); |
Nicholas75179 | 0:fde420d18f42 | 278 | #ifdef DEBUG_render |
Nicholas75179 | 0:fde420d18f42 | 279 | printf("Found enemy0: %3.1f,%3.1f\n", |
Nicholas75179 | 0:fde420d18f42 | 280 | enemy[0].pos_x, enemy[0].pos_y); |
Nicholas75179 | 0:fde420d18f42 | 281 | #endif |
Nicholas75179 | 0:fde420d18f42 | 282 | |
Nicholas75179 | 0:fde420d18f42 | 283 | } else if (extra_enemies && temp1 == int(enemy[1].pos_x) |
Nicholas75179 | 0:fde420d18f42 | 284 | && temp2 == int(enemy[1].pos_y)) { |
Nicholas75179 | 0:fde420d18f42 | 285 | draw_enemy(i, ii, 1); |
Nicholas75179 | 0:fde420d18f42 | 286 | #ifdef DEBUG_render |
Nicholas75179 | 0:fde420d18f42 | 287 | printf("Found enemy1: %3.1f,%3.1f\n", |
Nicholas75179 | 0:fde420d18f42 | 288 | enemy[1].pos_x, enemy[1].pos_y); |
Nicholas75179 | 0:fde420d18f42 | 289 | #endif |
Nicholas75179 | 0:fde420d18f42 | 290 | } |
Nicholas75179 | 0:fde420d18f42 | 291 | else if (check_stars(temp1, temp2) |
Nicholas75179 | 0:fde420d18f42 | 292 | || player.check_bullets(temp1, temp2) |
Nicholas75179 | 0:fde420d18f42 | 293 | || enemy[0].check_bullets(temp1, temp2) |
Nicholas75179 | 0:fde420d18f42 | 294 | || enemy[1].check_bullets(temp1, temp2)){ |
Nicholas75179 | 0:fde420d18f42 | 295 | lcd.setPixel(68-i, 24-ii, 1); |
Nicholas75179 | 0:fde420d18f42 | 296 | } |
Nicholas75179 | 0:fde420d18f42 | 297 | }// above finds the location of particles to render |
Nicholas75179 | 0:fde420d18f42 | 298 | } |
Nicholas75179 | 0:fde420d18f42 | 299 | } |
Nicholas75179 | 0:fde420d18f42 | 300 | |
Nicholas75179 | 0:fde420d18f42 | 301 | void draw_enemy(int i, int j, int num) { |
Nicholas75179 | 0:fde420d18f42 | 302 | float angle = player.orientation - enemy[num].orientation - 1.5708f; |
Nicholas75179 | 0:fde420d18f42 | 303 | //this calculation finds what direction |
Nicholas75179 | 0:fde420d18f42 | 304 | //to draw the enemy with respect to the player |
Nicholas75179 | 0:fde420d18f42 | 305 | |
Nicholas75179 | 0:fde420d18f42 | 306 | if (enemy[num].HP > 0) { |
Nicholas75179 | 0:fde420d18f42 | 307 | lcd.drawRect(63 - i, 32 - j, 12, 4, FILL_TRANSPARENT); //health bar |
Nicholas75179 | 0:fde420d18f42 | 308 | lcd.drawRect(64 - i, 33 - j, enemy[num].HP, 2, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 309 | |
Nicholas75179 | 0:fde420d18f42 | 310 | if (j < 20) {//limits the game to drawing within bound of the screen |
Nicholas75179 | 0:fde420d18f42 | 311 | lcd.drawCircle(68 - i, 24 - j, 5, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 312 | lcd.drawCircle(68 - i + 3 * sin(angle), |
Nicholas75179 | 0:fde420d18f42 | 313 | 24 - j + 3 * cos(angle), 2, FILL_WHITE); |
Nicholas75179 | 0:fde420d18f42 | 314 | } |
Nicholas75179 | 0:fde420d18f42 | 315 | } else if (explode (68 - i, 24 - j) && j < 20) { |
Nicholas75179 | 0:fde420d18f42 | 316 | lcd.drawCircle(68 - i, 24 - j, 5, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 317 | lcd.drawCircle(68 - i + 3 * sin(angle), |
Nicholas75179 | 0:fde420d18f42 | 318 | 24 - j + 3 * cos(angle), 2, FILL_WHITE); |
Nicholas75179 | 0:fde420d18f42 | 319 | } |
Nicholas75179 | 0:fde420d18f42 | 320 | } |
Nicholas75179 | 0:fde420d18f42 | 321 | |
Nicholas75179 | 0:fde420d18f42 | 322 | void effects(bool phase_two, int time_limit, float HP_divider) { |
Nicholas75179 | 0:fde420d18f42 | 323 | if (enemy[0].HP > 0) print_tracker(0); |
Nicholas75179 | 0:fde420d18f42 | 324 | if ((difficulty || phase_two) && (enemy[1].HP > 0)) print_tracker(1); |
Nicholas75179 | 0:fde420d18f42 | 325 | if (pad.X_held() && clock() % 18 > 8) { |
Nicholas75179 | 0:fde420d18f42 | 326 | for (int i = 0; i < 3; i++)lcd.setPixel(69 + i, 24 , 1); |
Nicholas75179 | 0:fde420d18f42 | 327 | if (clock() % 9 > 3) { |
Nicholas75179 | 0:fde420d18f42 | 328 | lcd.setPixel(72, 24, 1); |
Nicholas75179 | 0:fde420d18f42 | 329 | lcd.setPixel(73, 24, 1); |
Nicholas75179 | 0:fde420d18f42 | 330 | } |
Nicholas75179 | 0:fde420d18f42 | 331 | } |
Nicholas75179 | 0:fde420d18f42 | 332 | pad.leds(0); //LEDs display player health proportionally |
Nicholas75179 | 0:fde420d18f42 | 333 | if (player.HP > 0) { |
Nicholas75179 | 0:fde420d18f42 | 334 | for (int health = 0; health <= (HP_divider*player.HP); health++) { |
Nicholas75179 | 0:fde420d18f42 | 335 | pad.led(health, 1); |
Nicholas75179 | 0:fde420d18f42 | 336 | } |
Nicholas75179 | 0:fde420d18f42 | 337 | } |
Nicholas75179 | 0:fde420d18f42 | 338 | else explode(68, 24); |
Nicholas75179 | 0:fde420d18f42 | 339 | if (sound_on) sound(difficulty || phase_two); |
Nicholas75179 | 0:fde420d18f42 | 340 | sprintf(g_buffer, "%2i", (time_limit - clock()) / 100); |
Nicholas75179 | 0:fde420d18f42 | 341 | lcd.printString(g_buffer, 12, 5); |
Nicholas75179 | 0:fde420d18f42 | 342 | } |
Nicholas75179 | 0:fde420d18f42 | 343 | |
Nicholas75179 | 0:fde420d18f42 | 344 | void print_tracker(int num) { |
Nicholas75179 | 0:fde420d18f42 | 345 | float diff_x = enemy[num].pos_x-player.pos_x; |
Nicholas75179 | 0:fde420d18f42 | 346 | if (abs(diff_x) < 0.0001f) diff_x = 0.0001f; |
Nicholas75179 | 0:fde420d18f42 | 347 | |
Nicholas75179 | 0:fde420d18f42 | 348 | float angle_to_enemy = atan((enemy[num].pos_y - player.pos_y) / diff_x); |
Nicholas75179 | 0:fde420d18f42 | 349 | if ((diff_x) > 0) angle_to_enemy += 3.1416f; |
Nicholas75179 | 0:fde420d18f42 | 350 | |
Nicholas75179 | 0:fde420d18f42 | 351 | #ifdef DEBUG_tracker |
Nicholas75179 | 0:fde420d18f42 | 352 | sprintf(g_buffer, "%1.3f", player.orientation); |
Nicholas75179 | 0:fde420d18f42 | 353 | lcd.printString(g_buffer, 60, 0); |
Nicholas75179 | 0:fde420d18f42 | 354 | sprintf(g_buffer, "%1.3f", angle_to_enemy - player.orientation); |
Nicholas75179 | 0:fde420d18f42 | 355 | lcd.printString(g_buffer, 60, 1); |
Nicholas75179 | 0:fde420d18f42 | 356 | #endif |
Nicholas75179 | 0:fde420d18f42 | 357 | |
Nicholas75179 | 0:fde420d18f42 | 358 | float sine = sin(angle_to_enemy - player.orientation); |
Nicholas75179 | 0:fde420d18f42 | 359 | float cosine = cos(angle_to_enemy - player.orientation); |
Nicholas75179 | 0:fde420d18f42 | 360 | |
Nicholas75179 | 0:fde420d18f42 | 361 | lcd.setPixel(67 + 8 * cosine, 24 + 6 * sine, 1); |
Nicholas75179 | 0:fde420d18f42 | 362 | lcd.setPixel(67 + 9 * cosine, 24 + 7 * sine, 1); |
Nicholas75179 | 0:fde420d18f42 | 363 | lcd.setPixel(67 + 10 * cosine, 24 + 8 * sine, 1); |
Nicholas75179 | 0:fde420d18f42 | 364 | lcd.setPixel(67 + 11 * cosine, 24 + 9 * sine, 1); |
Nicholas75179 | 0:fde420d18f42 | 365 | lcd.setPixel(67 + 12 * cosine, 24 + 10 * sine, 1); |
Nicholas75179 | 0:fde420d18f42 | 366 | lcd.setPixel(67 + 13 * cosine, 24 + 11 * sine, 1); |
Nicholas75179 | 0:fde420d18f42 | 367 | lcd.drawCircle(67 + 9 * cosine, 24 + 7 * sine, 1, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 368 | lcd.drawCircle(67 + 10 * cosine, 24 + 8 * sine, 1, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 369 | } |
Nicholas75179 | 0:fde420d18f42 | 370 | |
Nicholas75179 | 0:fde420d18f42 | 371 | void sound(bool extra_enemy) { |
Nicholas75179 | 0:fde420d18f42 | 372 | //buzzers can only produce one tone at a time |
Nicholas75179 | 0:fde420d18f42 | 373 | //this function prioritises some sounds over others |
Nicholas75179 | 0:fde420d18f42 | 374 | if (player.HP <= 0) { |
Nicholas75179 | 0:fde420d18f42 | 375 | player.explosion_FX--; |
Nicholas75179 | 0:fde420d18f42 | 376 | } |
Nicholas75179 | 0:fde420d18f42 | 377 | if (enemy[0].HP <= 0) { |
Nicholas75179 | 0:fde420d18f42 | 378 | enemy[0].explosion_FX--; |
Nicholas75179 | 0:fde420d18f42 | 379 | } |
Nicholas75179 | 0:fde420d18f42 | 380 | if (extra_enemy && enemy[1].HP <= 0) { |
Nicholas75179 | 0:fde420d18f42 | 381 | enemy[1].explosion_FX--; |
Nicholas75179 | 0:fde420d18f42 | 382 | } |
Nicholas75179 | 0:fde420d18f42 | 383 | //"explosion" is initialised as 8, and is decremented each frame |
Nicholas75179 | 0:fde420d18f42 | 384 | //below if statement makes the explosion produce noise over 7 frames |
Nicholas75179 | 0:fde420d18f42 | 385 | if ((player.explosion_FX < 8 && player.explosion_FX > 0) |
Nicholas75179 | 0:fde420d18f42 | 386 | || (enemy[0].explosion_FX < 8 && enemy[0].explosion_FX > 0) |
Nicholas75179 | 0:fde420d18f42 | 387 | || (extra_enemy && enemy[1].explosion_FX < 8 && enemy[1].explosion_FX > 0)) { |
Nicholas75179 | 0:fde420d18f42 | 388 | pad.tone(1000, 0.1); |
Nicholas75179 | 0:fde420d18f42 | 389 | } |
Nicholas75179 | 0:fde420d18f42 | 390 | else if (player.gun_FX > 0) pad.tone(1600 - player.gun_FX * 200, 0.1); |
Nicholas75179 | 0:fde420d18f42 | 391 | //the player's weapon takes priority for sound, after explosions |
Nicholas75179 | 0:fde420d18f42 | 392 | else if (enemy[0].gun_FX > 0) pad.tone(5000, 0.1); |
Nicholas75179 | 0:fde420d18f42 | 393 | else if (enemy[1].gun_FX > 0) pad.tone(5000, 0.1); |
Nicholas75179 | 0:fde420d18f42 | 394 | |
Nicholas75179 | 0:fde420d18f42 | 395 | enemy[0].gun_FX--; |
Nicholas75179 | 0:fde420d18f42 | 396 | enemy[1].gun_FX--; |
Nicholas75179 | 0:fde420d18f42 | 397 | player.gun_FX--; |
Nicholas75179 | 0:fde420d18f42 | 398 | //decrementing the FX variable makes sure the sound is not delayed |
Nicholas75179 | 0:fde420d18f42 | 399 | //if the function is busy producing a different sound |
Nicholas75179 | 0:fde420d18f42 | 400 | } |
Nicholas75179 | 0:fde420d18f42 | 401 | |
Nicholas75179 | 0:fde420d18f42 | 402 | bool explode(int i, int j) { |
Nicholas75179 | 0:fde420d18f42 | 403 | //a clock() with a modulo helps make the explosion more exciting |
Nicholas75179 | 0:fde420d18f42 | 404 | //by forcing it to switch on and off over time |
Nicholas75179 | 0:fde420d18f42 | 405 | if (clock() % 9 > 4) { |
Nicholas75179 | 0:fde420d18f42 | 406 | for (int inc = 0; inc < 6; inc++) { |
Nicholas75179 | 0:fde420d18f42 | 407 | float b = rand() % 63 / 10; |
Nicholas75179 | 0:fde420d18f42 | 408 | int a = rand() % 6; |
Nicholas75179 | 0:fde420d18f42 | 409 | int tempx = i - a * sin(b), tempy = j - a * cos(b); |
Nicholas75179 | 0:fde420d18f42 | 410 | |
Nicholas75179 | 0:fde420d18f42 | 411 | if (tempy > 3 && i < 81) lcd.drawCircle(tempx, tempy, 2, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 412 | }//6 randomly placed white packets to simulate explosion |
Nicholas75179 | 0:fde420d18f42 | 413 | return 0; |
Nicholas75179 | 0:fde420d18f42 | 414 | }//boolean returns are used for switching a rendering function in draw_enemy(); |
Nicholas75179 | 0:fde420d18f42 | 415 | return 1; |
Nicholas75179 | 0:fde420d18f42 | 416 | } |
Nicholas75179 | 0:fde420d18f42 | 417 | |
Nicholas75179 | 0:fde420d18f42 | 418 | void print_background(float screen_x, float screen_y, float screen_orientation) { |
Nicholas75179 | 0:fde420d18f42 | 419 | int temp1, temp2; |
Nicholas75179 | 0:fde420d18f42 | 420 | float sine = sin(screen_orientation), cosine = cos(screen_orientation); |
Nicholas75179 | 0:fde420d18f42 | 421 | |
Nicholas75179 | 0:fde420d18f42 | 422 | for (int i = -16; i < 69; i++ ) { |
Nicholas75179 | 0:fde420d18f42 | 423 | for (int ii = -24; ii < 25; ii++) { |
Nicholas75179 | 0:fde420d18f42 | 424 | temp1 = int(screen_x + (i * cosine - ii * sine)); |
Nicholas75179 | 0:fde420d18f42 | 425 | temp2 = int(screen_y + (ii * cosine + i * sine)) + 1; |
Nicholas75179 | 0:fde420d18f42 | 426 | |
Nicholas75179 | 0:fde420d18f42 | 427 | if (check_stars(temp1, temp2)) lcd.setPixel(68 - i, 24 - ii, 1); |
Nicholas75179 | 0:fde420d18f42 | 428 | } |
Nicholas75179 | 0:fde420d18f42 | 429 | } |
Nicholas75179 | 0:fde420d18f42 | 430 | } |
Nicholas75179 | 0:fde420d18f42 | 431 | |
Nicholas75179 | 0:fde420d18f42 | 432 | bool check_stars(int temp1, int temp2) { |
Nicholas75179 | 0:fde420d18f42 | 433 | while (temp1 < 0) temp1 += 224; |
Nicholas75179 | 0:fde420d18f42 | 434 | temp1 = temp1 % 224; //this function tesselates the star map |
Nicholas75179 | 0:fde420d18f42 | 435 | while (temp2 < 0) temp2 += 224; |
Nicholas75179 | 0:fde420d18f42 | 436 | temp2 = temp2 % 224; |
Nicholas75179 | 0:fde420d18f42 | 437 | |
Nicholas75179 | 0:fde420d18f42 | 438 | if (g_star_map[temp1][temp2])return 1; |
Nicholas75179 | 0:fde420d18f42 | 439 | else return 0; |
Nicholas75179 | 0:fde420d18f42 | 440 | } |
Nicholas75179 | 0:fde420d18f42 | 441 | |
Nicholas75179 | 0:fde420d18f42 | 442 | void create_stars() {//the backhround is a boolean array |
Nicholas75179 | 0:fde420d18f42 | 443 | for (int i = 0; i < 224; i++) { |
Nicholas75179 | 0:fde420d18f42 | 444 | for (int ii = 0; ii < 224; ii++) g_star_map[i][ii] = 0; |
Nicholas75179 | 0:fde420d18f42 | 445 | }//this clears the background for drawing a new one |
Nicholas75179 | 0:fde420d18f42 | 446 | for (int i = 0; i < 224; i++) { |
Nicholas75179 | 0:fde420d18f42 | 447 | for (int ii = 0; ii < 224; ii++) { |
Nicholas75179 | 0:fde420d18f42 | 448 | if (rand() % 1000 > 985) g_star_map[i][ii] = 1; |
Nicholas75179 | 0:fde420d18f42 | 449 | }//1.5% of the sky is stars! |
Nicholas75179 | 0:fde420d18f42 | 450 | } |
Nicholas75179 | 0:fde420d18f42 | 451 | } |
Nicholas75179 | 0:fde420d18f42 | 452 | |
Nicholas75179 | 0:fde420d18f42 | 453 | void title_sequence() { |
Nicholas75179 | 0:fde420d18f42 | 454 | temptime = clock(); |
Nicholas75179 | 0:fde420d18f42 | 455 | |
Nicholas75179 | 0:fde420d18f42 | 456 | while ((clock() - temptime) < 40) { |
Nicholas75179 | 0:fde420d18f42 | 457 | lcd.clear(); |
Nicholas75179 | 0:fde420d18f42 | 458 | print_background(1, 0, 0); |
Nicholas75179 | 0:fde420d18f42 | 459 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 460 | } |
Nicholas75179 | 0:fde420d18f42 | 461 | sprintf(g_buffer, "Space Combat"); |
Nicholas75179 | 0:fde420d18f42 | 462 | |
Nicholas75179 | 0:fde420d18f42 | 463 | while (!pad.A_held() && !pad.B_held() && !pad.Y_held() |
Nicholas75179 | 0:fde420d18f42 | 464 | && !pad.X_held() && !pad.start_held()) { |
Nicholas75179 | 0:fde420d18f42 | 465 | AGALAG.render(lcd, 18, 12); |
Nicholas75179 | 0:fde420d18f42 | 466 | if ((clock() - temptime) < 240) dramatic_print(g_buffer, 7, 3, 20); |
Nicholas75179 | 0:fde420d18f42 | 467 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 468 | } |
Nicholas75179 | 0:fde420d18f42 | 469 | temptime = clock(); |
Nicholas75179 | 0:fde420d18f42 | 470 | |
Nicholas75179 | 0:fde420d18f42 | 471 | while (clock() - temptime < 140 && !pad.start_held()) { |
Nicholas75179 | 0:fde420d18f42 | 472 | lcd.clear(); |
Nicholas75179 | 0:fde420d18f42 | 473 | print_background(1, 0, 0); |
Nicholas75179 | 0:fde420d18f42 | 474 | AGALAG.render(lcd, 18, 11 - (clock() - temptime) / 20); |
Nicholas75179 | 0:fde420d18f42 | 475 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 476 | } |
Nicholas75179 | 0:fde420d18f42 | 477 | } |
Nicholas75179 | 0:fde420d18f42 | 478 | |
Nicholas75179 | 0:fde420d18f42 | 479 | void dramatic_print(string str, int offset, int line_num, int delay_time) { |
Nicholas75179 | 0:fde420d18f42 | 480 | int i = ((clock() - temptime) / delay_time) % 14; |
Nicholas75179 | 0:fde420d18f42 | 481 | |
Nicholas75179 | 0:fde420d18f42 | 482 | for (int ii = 0; ii <= i; ii++) { |
Nicholas75179 | 0:fde420d18f42 | 483 | lcd.printChar(str[ii], 6 * ii + offset, line_num); |
Nicholas75179 | 0:fde420d18f42 | 484 | } |
Nicholas75179 | 0:fde420d18f42 | 485 | } |
Nicholas75179 | 0:fde420d18f42 | 486 | |
Nicholas75179 | 0:fde420d18f42 | 487 | void help() { |
Nicholas75179 | 0:fde420d18f42 | 488 | while (pad.A_held() || pad.Y_held()); |
Nicholas75179 | 0:fde420d18f42 | 489 | pad.leds(1.0); |
Nicholas75179 | 0:fde420d18f42 | 490 | |
Nicholas75179 | 0:fde420d18f42 | 491 | while (!pad.A_held() && !pad.B_held() && !pad.Y_held() |
Nicholas75179 | 0:fde420d18f42 | 492 | && !pad.X_held() && !pad.start_held()) { |
Nicholas75179 | 0:fde420d18f42 | 493 | Vector2D coord = pad.get_mapped_coord(); |
Nicholas75179 | 0:fde420d18f42 | 494 | lcd.clear(); |
Nicholas75179 | 0:fde420d18f42 | 495 | print_background(1, 0, 0); |
Nicholas75179 | 0:fde420d18f42 | 496 | lcd.printString("<HP=LED>", 19, 0); |
Nicholas75179 | 0:fde420d18f42 | 497 | lcd.printString("<SHOOT>", 0, 1); |
Nicholas75179 | 0:fde420d18f42 | 498 | lcd.printString("<MOVE>", 45, 1); |
Nicholas75179 | 0:fde420d18f42 | 499 | lcd.printString(">BACK<", 24, 5); |
Nicholas75179 | 0:fde420d18f42 | 500 | lcd.drawCircle(63, 36, 3, FILL_TRANSPARENT); |
Nicholas75179 | 0:fde420d18f42 | 501 | lcd.drawCircle(63, 20, 3, FILL_TRANSPARENT); |
Nicholas75179 | 0:fde420d18f42 | 502 | lcd.drawCircle(53, 28, 3, FILL_TRANSPARENT); |
Nicholas75179 | 0:fde420d18f42 | 503 | lcd.drawCircle(73, 28, 3, FILL_TRANSPARENT); |
Nicholas75179 | 0:fde420d18f42 | 504 | lcd.drawCircle(20 + int(10 * coord.x), |
Nicholas75179 | 0:fde420d18f42 | 505 | 28 - int(10 * coord.y), 3, FILL_BLACK); |
Nicholas75179 | 0:fde420d18f42 | 506 | |
Nicholas75179 | 0:fde420d18f42 | 507 | if (clock() % 4 > 1) lcd.drawCircle(20, 28, 12, FILL_TRANSPARENT); |
Nicholas75179 | 0:fde420d18f42 | 508 | lcd.refresh(); |
Nicholas75179 | 0:fde420d18f42 | 509 | } |
Nicholas75179 | 0:fde420d18f42 | 510 | pad.leds(0); |
Nicholas75179 | 0:fde420d18f42 | 511 | } |