![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Revenge of the Mouse
Dependencies: 4DGL-uLCD-SE EthernetInterface Game_Synchronizer LCD_fonts MMA8452 SDFileSystem mbed-rtos mbed wave_player
Fork of 2035_Tanks_Shell by
main.cpp@24:2100c9e8ec81, 2015-10-30 (annotated)
- Committer:
- jford38
- Date:
- Fri Oct 30 09:01:48 2015 +0000
- Revision:
- 24:2100c9e8ec81
- Parent:
- 23:77049670cae6
- Child:
- 27:bd55ab4d137c
Final final final final final. Never looking at this again. Until I find something else to change :)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jford38 | 6:3be57cf4bd33 | 1 | // Student Side. |
jford38 | 0:899c85cd266f | 2 | |
jford38 | 0:899c85cd266f | 3 | #include "mbed.h" |
jford38 | 15:4b27a3a95772 | 4 | |
jford38 | 17:7bc7127782e4 | 5 | #include "SDFileSystem.h" |
jford38 | 17:7bc7127782e4 | 6 | #include "wave_player.h" |
jford38 | 6:3be57cf4bd33 | 7 | #include "game_synchronizer.h" |
jford38 | 14:36c306e26317 | 8 | #include "tank.h" |
jford38 | 15:4b27a3a95772 | 9 | #include "bullet.h" |
jford38 | 20:6a58052b0140 | 10 | #include "misc.h" |
jford38 | 10:5da9b27e050e | 11 | |
jford38 | 17:7bc7127782e4 | 12 | |
jford38 | 6:3be57cf4bd33 | 13 | DigitalOut led1(LED1); |
jford38 | 6:3be57cf4bd33 | 14 | DigitalOut led2(LED2); |
jford38 | 6:3be57cf4bd33 | 15 | DigitalOut led3(LED3); |
jford38 | 6:3be57cf4bd33 | 16 | DigitalOut led4(LED4); |
jford38 | 0:899c85cd266f | 17 | |
jford38 | 17:7bc7127782e4 | 18 | DigitalIn pb_u(p21); // Up Button |
jford38 | 17:7bc7127782e4 | 19 | DigitalIn pb_r(p22); // Right Button |
jford38 | 17:7bc7127782e4 | 20 | DigitalIn pb_d(p23); // Down Button |
jford38 | 17:7bc7127782e4 | 21 | DigitalIn pb_l(p24); // Left Button |
jford38 | 6:3be57cf4bd33 | 22 | |
jford38 | 17:7bc7127782e4 | 23 | Serial pc(USBTX, USBRX); // Serial connection to PC. Useful for debugging! |
jford38 | 17:7bc7127782e4 | 24 | MMA8452 acc(p28, p27, 100000); // Accelerometer (SDA, SCL, Baudrate) |
jford38 | 17:7bc7127782e4 | 25 | uLCD_4DGL uLCD(p9,p10,p11); // LCD (tx, rx, reset) |
jford38 | 17:7bc7127782e4 | 26 | SDFileSystem sd(p5, p6, p7, p8, "sd"); // SD (mosi, miso, sck, cs) |
jford38 | 17:7bc7127782e4 | 27 | AnalogOut DACout(p18); // speaker |
jford38 | 17:7bc7127782e4 | 28 | wave_player player(&DACout); // wav player |
jford38 | 17:7bc7127782e4 | 29 | Game_Synchronizer sync(PLAYER1); // Game_Synchronizer (PLAYER) |
jford38 | 17:7bc7127782e4 | 30 | Timer frame_timer; // Timer |
jford38 | 0:899c85cd266f | 31 | |
jford38 | 20:6a58052b0140 | 32 | // Global variables go here. |
jford38 | 22:3c68eea5a609 | 33 | |
jford38 | 23:77049670cae6 | 34 | int winner = -1; |
jford38 | 23:77049670cae6 | 35 | int whose_turn = PLAYER1; |
jford38 | 20:6a58052b0140 | 36 | |
jford38 | 20:6a58052b0140 | 37 | |
jford38 | 17:7bc7127782e4 | 38 | // Ask the user whether to run the game in Single- or Multi-Player mode. |
jford38 | 17:7bc7127782e4 | 39 | // Note that this function uses uLCD instead of sync because it is only |
jford38 | 17:7bc7127782e4 | 40 | // writing to the local (Player1) lcd. Sync hasn't been initialized yet, |
jford38 | 17:7bc7127782e4 | 41 | // so you can't use it anyway. For the same reason, you must access |
jford38 | 17:7bc7127782e4 | 42 | // the buttons directly e.g. if( !pb_r ) { do something; }. |
jford38 | 22:3c68eea5a609 | 43 | |
jford38 | 22:3c68eea5a609 | 44 | // return MULTI_PLAYER if the user selects multi-player. |
jford38 | 22:3c68eea5a609 | 45 | // return SINGLE_PLAYER if the user selects single-player. |
jford38 | 7:9506f2d84162 | 46 | int game_menu(void) { |
jford38 | 7:9506f2d84162 | 47 | |
jford38 | 18:18dfc9fb33b5 | 48 | uLCD.baudrate(BAUD_3000000); |
jford38 | 22:3c68eea5a609 | 49 | |
jford38 | 22:3c68eea5a609 | 50 | // the locate command tells the screen where to place the text. |
jford38 | 22:3c68eea5a609 | 51 | uLCD.locate(0,15); |
jford38 | 22:3c68eea5a609 | 52 | uLCD.puts("Replace me"); |
jford38 | 17:7bc7127782e4 | 53 | |
jford38 | 22:3c68eea5a609 | 54 | // Button Example: |
jford38 | 22:3c68eea5a609 | 55 | // Use !pb_r to access the player1 right button value. |
jford38 | 23:77049670cae6 | 56 | |
jford38 | 23:77049670cae6 | 57 | wait(2); // Eventually you can take this out. |
jford38 | 23:77049670cae6 | 58 | |
jford38 | 23:77049670cae6 | 59 | // Eventually you should return SINGLE_PLAYER or MULTI_PLAYER |
jford38 | 23:77049670cae6 | 60 | // depending on the user's choice. |
jford38 | 23:77049670cae6 | 61 | return SINGLE_PLAYER; |
jford38 | 7:9506f2d84162 | 62 | } |
jford38 | 7:9506f2d84162 | 63 | |
jford38 | 17:7bc7127782e4 | 64 | // Initialize the world map. I've provided a basic map here, |
jford38 | 17:7bc7127782e4 | 65 | // but as part of the assignment you must create more |
jford38 | 17:7bc7127782e4 | 66 | // interesting map(s). |
jford38 | 17:7bc7127782e4 | 67 | // Note that calls to sync.function() will run function() |
jford38 | 17:7bc7127782e4 | 68 | // on both players' LCDs (assuming you are in multiplayer mode). |
jford38 | 17:7bc7127782e4 | 69 | // In single player mode, only your lcd will be modified. (Makes sense, right?) |
jford38 | 10:5da9b27e050e | 70 | void map_init() { |
jford38 | 17:7bc7127782e4 | 71 | |
jford38 | 17:7bc7127782e4 | 72 | // Fill the entire screen with sky blue. |
jford38 | 10:5da9b27e050e | 73 | sync.background_color(SKY_COLOR); |
jford38 | 17:7bc7127782e4 | 74 | |
jford38 | 17:7bc7127782e4 | 75 | // Call the clear screen function to force the LCD to redraw the screen |
jford38 | 17:7bc7127782e4 | 76 | // with the new background color. |
jford38 | 10:5da9b27e050e | 77 | sync.cls(); |
jford38 | 17:7bc7127782e4 | 78 | |
jford38 | 17:7bc7127782e4 | 79 | // Draw the ground in green. |
jford38 | 10:5da9b27e050e | 80 | sync.filled_rectangle(0,0,128,20, GND_COLOR); |
jford38 | 17:7bc7127782e4 | 81 | |
jford38 | 22:3c68eea5a609 | 82 | // Draw some obstacles. They don't have to be black, |
jford38 | 22:3c68eea5a609 | 83 | // but they shouldn't be the same color as the sky or your tanks. |
jford38 | 17:7bc7127782e4 | 84 | // Get creative here. You could use brown and grey to draw a mountain |
jford38 | 17:7bc7127782e4 | 85 | // or something cool like that. |
jford38 | 10:5da9b27e050e | 86 | sync.filled_rectangle(59, 20, 69, 60, BLACK); |
jford38 | 17:7bc7127782e4 | 87 | |
jford38 | 17:7bc7127782e4 | 88 | // Before you write text on the screens, tell the LCD where to put it. |
jford38 | 17:7bc7127782e4 | 89 | sync.locate(0,15); |
jford38 | 17:7bc7127782e4 | 90 | |
jford38 | 20:6a58052b0140 | 91 | // Set the text background color to match the sky. Just for looks. |
jford38 | 14:36c306e26317 | 92 | sync.textbackground_color(SKY_COLOR); |
jford38 | 22:3c68eea5a609 | 93 | |
jford38 | 20:6a58052b0140 | 94 | // Display the game title. |
jford38 | 22:3c68eea5a609 | 95 | char title[] = " Title"; |
jford38 | 17:7bc7127782e4 | 96 | sync.puts(title, sizeof(title)); |
jford38 | 23:77049670cae6 | 97 | |
jford38 | 23:77049670cae6 | 98 | // Flush the draw buffer and execute all the accumulated draw commands. |
jford38 | 23:77049670cae6 | 99 | sync.update(); |
jford38 | 10:5da9b27e050e | 100 | } |
jford38 | 10:5da9b27e050e | 101 | |
jford38 | 21:edfeb289b21f | 102 | // Initialize the game hardware. |
jford38 | 21:edfeb289b21f | 103 | // Call game_menu to find out which mode to play the game in (Single- or Multi-Player) |
jford38 | 21:edfeb289b21f | 104 | // Initialize the game synchronizer. |
jford38 | 6:3be57cf4bd33 | 105 | void game_init(void) { |
jford38 | 6:3be57cf4bd33 | 106 | |
jford38 | 6:3be57cf4bd33 | 107 | led1 = 0; led2 = 0; led3 = 0; led4 = 0; |
jford38 | 6:3be57cf4bd33 | 108 | |
jford38 | 17:7bc7127782e4 | 109 | pb_u.mode(PullUp); |
jford38 | 6:3be57cf4bd33 | 110 | pb_r.mode(PullUp); |
jford38 | 17:7bc7127782e4 | 111 | pb_d.mode(PullUp); |
jford38 | 17:7bc7127782e4 | 112 | pb_l.mode(PullUp); |
jford38 | 6:3be57cf4bd33 | 113 | |
jford38 | 6:3be57cf4bd33 | 114 | pc.printf("\033[2J\033[0;0H"); // Clear the terminal screen. |
jford38 | 6:3be57cf4bd33 | 115 | pc.printf("I'm alive! Player 1\n"); // Let us know you made it this far. |
jford38 | 7:9506f2d84162 | 116 | int mode = game_menu(); |
jford38 | 17:7bc7127782e4 | 117 | sync.init(&uLCD, &acc, &pb_u, &pb_r, &pb_d, &pb_l, mode); // Connect to the other player. |
jford38 | 10:5da9b27e050e | 118 | map_init(); |
jford38 | 6:3be57cf4bd33 | 119 | pc.printf("Initialized...\n"); // Let us know you finished initializing. |
jford38 | 6:3be57cf4bd33 | 120 | } |
jford38 | 6:3be57cf4bd33 | 121 | |
jford38 | 22:3c68eea5a609 | 122 | // Display some kind of game over screen which lets us know who won. |
jford38 | 22:3c68eea5a609 | 123 | // Play a cool sound! |
jford38 | 22:3c68eea5a609 | 124 | void game_over() { |
jford38 | 22:3c68eea5a609 | 125 | |
jford38 | 19:7aa3af04d6a8 | 126 | } |
jford38 | 19:7aa3af04d6a8 | 127 | |
jford38 | 21:edfeb289b21f | 128 | |
jford38 | 0:899c85cd266f | 129 | int main (void) { |
jford38 | 20:6a58052b0140 | 130 | |
jford38 | 20:6a58052b0140 | 131 | int* p1_buttons; |
jford38 | 20:6a58052b0140 | 132 | int* p2_buttons; |
jford38 | 20:6a58052b0140 | 133 | |
jford38 | 20:6a58052b0140 | 134 | float ax1, ay1, az1; |
jford38 | 20:6a58052b0140 | 135 | float ax2, ay2, az2; |
jford38 | 8:e6dd05393290 | 136 | |
jford38 | 8:e6dd05393290 | 137 | game_init(); |
jford38 | 8:e6dd05393290 | 138 | |
jford38 | 22:3c68eea5a609 | 139 | // Create your tanks. |
jford38 | 18:18dfc9fb33b5 | 140 | Tank t1(4, 21, 12, 8, TANK_RED); // (min_x, min_y, width, height, color) |
jford38 | 18:18dfc9fb33b5 | 141 | Tank t2(111, 21, 12, 8, TANK_BLUE); // (min_x, min_y, width, height, color) |
jford38 | 22:3c68eea5a609 | 142 | |
jford38 | 22:3c68eea5a609 | 143 | // For each tank, create a bullet. |
jford38 | 12:088a8203a9bb | 144 | Bullet b1(&t1); |
jford38 | 12:088a8203a9bb | 145 | Bullet b2(&t2); |
jford38 | 12:088a8203a9bb | 146 | |
jford38 | 23:77049670cae6 | 147 | frame_timer.start(); |
jford38 | 5:cfec780c935b | 148 | |
jford38 | 23:77049670cae6 | 149 | // Your code starts here... |
jford38 | 20:6a58052b0140 | 150 | while(true) { |
jford38 | 24:2100c9e8ec81 | 151 | |
jford38 | 23:77049670cae6 | 152 | // Get a pointer to the buttons for both sides. |
jford38 | 23:77049670cae6 | 153 | // From now on, you can access the buttons for player x using |
jford38 | 23:77049670cae6 | 154 | // |
jford38 | 23:77049670cae6 | 155 | // px_buttons[U_BUTTON] |
jford38 | 23:77049670cae6 | 156 | // px_buttons[R_BUTTON] |
jford38 | 23:77049670cae6 | 157 | // px_buttons[D_BUTTON] |
jford38 | 23:77049670cae6 | 158 | // px_buttons[L_BUTTON] |
jford38 | 12:088a8203a9bb | 159 | |
jford38 | 20:6a58052b0140 | 160 | p1_buttons = sync.get_p1_buttons(); |
jford38 | 20:6a58052b0140 | 161 | p2_buttons = sync.get_p2_buttons(); |
jford38 | 23:77049670cae6 | 162 | |
jford38 | 23:77049670cae6 | 163 | led1 = p1_buttons[0] ^ p2_buttons[0]; |
jford38 | 23:77049670cae6 | 164 | led2 = p1_buttons[1] ^ p2_buttons[1]; |
jford38 | 23:77049670cae6 | 165 | led3 = p1_buttons[2] ^ p2_buttons[2]; |
jford38 | 23:77049670cae6 | 166 | led4 = p1_buttons[3] ^ p2_buttons[3]; |
jford38 | 20:6a58052b0140 | 167 | |
jford38 | 22:3c68eea5a609 | 168 | // Get the accelerometer values. |
jford38 | 22:3c68eea5a609 | 169 | sync.get_p1_accel_data(&ax1, &ay1, &az1); |
jford38 | 22:3c68eea5a609 | 170 | sync.get_p2_accel_data(&ax2, &ay2, &az2); |
jford38 | 22:3c68eea5a609 | 171 | |
jford38 | 23:77049670cae6 | 172 | if(whose_turn == PLAYER1) { |
jford38 | 23:77049670cae6 | 173 | |
jford38 | 23:77049670cae6 | 174 | // Accelerometer example |
jford38 | 23:77049670cae6 | 175 | if(ax1 > ACC_THRESHOLD) { |
jford38 | 23:77049670cae6 | 176 | // Move the tank to the right if the accelerometer is tipped far enough to the right. |
jford38 | 23:77049670cae6 | 177 | t1.reposition(+1, 0, 0); |
jford38 | 23:77049670cae6 | 178 | } |
jford38 | 23:77049670cae6 | 179 | |
jford38 | 23:77049670cae6 | 180 | // Button example |
jford38 | 23:77049670cae6 | 181 | if(p1_buttons[D_BUTTON]) { |
jford38 | 23:77049670cae6 | 182 | b1.shoot(); |
jford38 | 23:77049670cae6 | 183 | } |
jford38 | 23:77049670cae6 | 184 | |
jford38 | 23:77049670cae6 | 185 | float dt = frame_timer.read(); |
jford38 | 23:77049670cae6 | 186 | int intersection_code = b1.time_step(dt); |
jford38 | 23:77049670cae6 | 187 | |
jford38 | 23:77049670cae6 | 188 | if(intersection_code != BULLET_NO_COLLISION || intersection_code == BULLET_OFF_SCREEN) { |
jford38 | 23:77049670cae6 | 189 | pc.printf("Now it's P2's turn!\n"); |
jford38 | 23:77049670cae6 | 190 | whose_turn = PLAYER2; |
jford38 | 23:77049670cae6 | 191 | } |
jford38 | 23:77049670cae6 | 192 | |
jford38 | 23:77049670cae6 | 193 | // If you shot yourself, you lost. |
jford38 | 23:77049670cae6 | 194 | if(sync.pixel_eq(intersection_code, t1.tank_color)) { |
jford38 | 23:77049670cae6 | 195 | sync.update(); // Is this necessary? |
jford38 | 23:77049670cae6 | 196 | winner = PLAYER2; |
jford38 | 23:77049670cae6 | 197 | break; |
jford38 | 23:77049670cae6 | 198 | } |
jford38 | 23:77049670cae6 | 199 | |
jford38 | 23:77049670cae6 | 200 | // If you shot the other guy, you won! |
jford38 | 23:77049670cae6 | 201 | if(sync.pixel_eq(intersection_code, t2.tank_color)) { |
jford38 | 23:77049670cae6 | 202 | sync.update(); |
jford38 | 23:77049670cae6 | 203 | winner = PLAYER1; |
jford38 | 23:77049670cae6 | 204 | break; |
jford38 | 23:77049670cae6 | 205 | } |
jford38 | 23:77049670cae6 | 206 | } else if(whose_turn == PLAYER2) { |
jford38 | 23:77049670cae6 | 207 | |
jford38 | 23:77049670cae6 | 208 | // I gave you a lot of the logic for Player1. It's up to you to figure out Player2! |
jford38 | 23:77049670cae6 | 209 | // If you are in SINGLE_PLAYER mode, you should use the p1 inputs to control p2. |
jford38 | 23:77049670cae6 | 210 | // In MULTI_PLAYER mode, you should use the p2 inputs to control p2. |
jford38 | 23:77049670cae6 | 211 | // |
jford38 | 23:77049670cae6 | 212 | // Hint: |
jford38 | 23:77049670cae6 | 213 | // sync.play_mode will tell you if you are in MULTI_PLAYER or SINGLE_PLAYER mode. |
jford38 | 23:77049670cae6 | 214 | // |
jford38 | 23:77049670cae6 | 215 | |
jford38 | 23:77049670cae6 | 216 | } |
jford38 | 23:77049670cae6 | 217 | |
jford38 | 23:77049670cae6 | 218 | frame_timer.reset(); |
jford38 | 23:77049670cae6 | 219 | sync.update(); |
jford38 | 3:3ddefff03cb2 | 220 | } |
jford38 | 15:4b27a3a95772 | 221 | |
jford38 | 22:3c68eea5a609 | 222 | game_over(); |
jford38 | 21:edfeb289b21f | 223 | |
jford38 | 0:899c85cd266f | 224 | } |