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@17:7bc7127782e4, 2015-10-28 (annotated)
- Committer:
- jford38
- Date:
- Wed Oct 28 04:30:22 2015 +0000
- Revision:
- 17:7bc7127782e4
- Parent:
- 16:b73f0842d3cd
- Child:
- 18:18dfc9fb33b5
Works with updates to game synchronizer. The synchronizer now contains buttons/accelerometers.
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 "Speaker.h" |
jford38 | 17:7bc7127782e4 | 7 | #include "wave_player.h" |
jford38 | 17:7bc7127782e4 | 8 | |
jford38 | 6:3be57cf4bd33 | 9 | #include "game_synchronizer.h" |
jford38 | 14:36c306e26317 | 10 | #include "tank.h" |
jford38 | 15:4b27a3a95772 | 11 | #include "bullet.h" |
jford38 | 14:36c306e26317 | 12 | #include "globals.h" |
jford38 | 10:5da9b27e050e | 13 | |
jford38 | 17:7bc7127782e4 | 14 | |
jford38 | 6:3be57cf4bd33 | 15 | DigitalOut led1(LED1); |
jford38 | 6:3be57cf4bd33 | 16 | DigitalOut led2(LED2); |
jford38 | 6:3be57cf4bd33 | 17 | DigitalOut led3(LED3); |
jford38 | 6:3be57cf4bd33 | 18 | DigitalOut led4(LED4); |
jford38 | 0:899c85cd266f | 19 | |
jford38 | 17:7bc7127782e4 | 20 | DigitalIn pb_u(p21); // Up Button |
jford38 | 17:7bc7127782e4 | 21 | DigitalIn pb_r(p22); // Right Button |
jford38 | 17:7bc7127782e4 | 22 | DigitalIn pb_d(p23); // Down Button |
jford38 | 17:7bc7127782e4 | 23 | DigitalIn pb_l(p24); // Left Button |
jford38 | 6:3be57cf4bd33 | 24 | |
jford38 | 17:7bc7127782e4 | 25 | Serial pc(USBTX, USBRX); // Serial connection to PC. Useful for debugging! |
jford38 | 17:7bc7127782e4 | 26 | MMA8452 acc(p28, p27, 100000); // Accelerometer (SDA, SCL, Baudrate) |
jford38 | 17:7bc7127782e4 | 27 | uLCD_4DGL uLCD(p9,p10,p11); // LCD (tx, rx, reset) |
jford38 | 17:7bc7127782e4 | 28 | SDFileSystem sd(p5, p6, p7, p8, "sd"); // SD (mosi, miso, sck, cs) |
jford38 | 17:7bc7127782e4 | 29 | AnalogOut DACout(p18); // speaker |
jford38 | 17:7bc7127782e4 | 30 | wave_player player(&DACout); // wav player |
jford38 | 17:7bc7127782e4 | 31 | Game_Synchronizer sync(PLAYER1); // Game_Synchronizer (PLAYER) |
jford38 | 17:7bc7127782e4 | 32 | Timer frame_timer; // Timer |
jford38 | 0:899c85cd266f | 33 | |
jford38 | 7:9506f2d84162 | 34 | |
jford38 | 17:7bc7127782e4 | 35 | |
jford38 | 17:7bc7127782e4 | 36 | // Ask the user whether to run the game in Single- or Multi-Player mode. |
jford38 | 17:7bc7127782e4 | 37 | // Note that this function uses uLCD instead of sync because it is only |
jford38 | 17:7bc7127782e4 | 38 | // writing to the local (Player1) lcd. Sync hasn't been initialized yet, |
jford38 | 17:7bc7127782e4 | 39 | // so you can't use it anyway. For the same reason, you must access |
jford38 | 17:7bc7127782e4 | 40 | // the buttons directly e.g. if( !pb_r ) { do something; }. |
jford38 | 7:9506f2d84162 | 41 | int game_menu(void) { |
jford38 | 7:9506f2d84162 | 42 | |
jford38 | 9:ee330b1ba394 | 43 | uLCD.locate(0,1); |
jford38 | 9:ee330b1ba394 | 44 | uLCD.puts("Select Mode:"); |
jford38 | 9:ee330b1ba394 | 45 | uLCD.locate(0,3); |
jford38 | 9:ee330b1ba394 | 46 | uLCD.puts(" Single-Player:"); |
jford38 | 9:ee330b1ba394 | 47 | uLCD.locate(0,4); |
jford38 | 9:ee330b1ba394 | 48 | uLCD.puts(" Left Button"); |
jford38 | 9:ee330b1ba394 | 49 | uLCD.locate(0,6); |
jford38 | 9:ee330b1ba394 | 50 | uLCD.puts(" Multi-Player:"); |
jford38 | 9:ee330b1ba394 | 51 | uLCD.locate(0,7); |
jford38 | 9:ee330b1ba394 | 52 | uLCD.puts(" Right Button"); |
jford38 | 17:7bc7127782e4 | 53 | |
jford38 | 7:9506f2d84162 | 54 | while(1) { |
jford38 | 17:7bc7127782e4 | 55 | if(!pb_r) { return MULTI_PLAYER; } // Right button -> Multiplayer |
jford38 | 17:7bc7127782e4 | 56 | if(!pb_l) { return SINGLE_PLAYER; } // Left button -> Single player |
jford38 | 7:9506f2d84162 | 57 | } |
jford38 | 7:9506f2d84162 | 58 | } |
jford38 | 7:9506f2d84162 | 59 | |
jford38 | 17:7bc7127782e4 | 60 | // Initialize the world map. I've provided a basic map here, |
jford38 | 17:7bc7127782e4 | 61 | // but as part of the assignment you must create more |
jford38 | 17:7bc7127782e4 | 62 | // interesting map(s). |
jford38 | 17:7bc7127782e4 | 63 | // Note that calls to sync.function() will run function() |
jford38 | 17:7bc7127782e4 | 64 | // on both players' LCDs (assuming you are in multiplayer mode). |
jford38 | 17:7bc7127782e4 | 65 | // In single player mode, only your lcd will be modified. (Makes sense, right?) |
jford38 | 10:5da9b27e050e | 66 | void map_init() { |
jford38 | 17:7bc7127782e4 | 67 | |
jford38 | 17:7bc7127782e4 | 68 | // Fill the entire screen with sky blue. |
jford38 | 10:5da9b27e050e | 69 | sync.background_color(SKY_COLOR); |
jford38 | 17:7bc7127782e4 | 70 | |
jford38 | 17:7bc7127782e4 | 71 | // Call the clear screen function to force the LCD to redraw the screen |
jford38 | 17:7bc7127782e4 | 72 | // with the new background color. |
jford38 | 10:5da9b27e050e | 73 | sync.cls(); |
jford38 | 17:7bc7127782e4 | 74 | |
jford38 | 17:7bc7127782e4 | 75 | // Draw the ground in green. |
jford38 | 10:5da9b27e050e | 76 | sync.filled_rectangle(0,0,128,20, GND_COLOR); |
jford38 | 17:7bc7127782e4 | 77 | |
jford38 | 17:7bc7127782e4 | 78 | // Draw a wall in the middle of the map. It doesn't have to be black, |
jford38 | 17:7bc7127782e4 | 79 | // but it shouldn't be the same color as the sky or your tanks. |
jford38 | 17:7bc7127782e4 | 80 | // Get creative here. You could use brown and grey to draw a mountain |
jford38 | 17:7bc7127782e4 | 81 | // or something cool like that. |
jford38 | 10:5da9b27e050e | 82 | sync.filled_rectangle(59, 20, 69, 60, BLACK); |
jford38 | 17:7bc7127782e4 | 83 | |
jford38 | 17:7bc7127782e4 | 84 | // Before you write text on the screens, tell the LCD where to put it. |
jford38 | 17:7bc7127782e4 | 85 | sync.locate(0,15); |
jford38 | 17:7bc7127782e4 | 86 | |
jford38 | 14:36c306e26317 | 87 | sync.textbackground_color(SKY_COLOR); |
jford38 | 17:7bc7127782e4 | 88 | char title[] = " ECE 2035 Tanks"; |
jford38 | 17:7bc7127782e4 | 89 | sync.puts(title, sizeof(title)); |
jford38 | 10:5da9b27e050e | 90 | sync.update(); |
jford38 | 10:5da9b27e050e | 91 | } |
jford38 | 10:5da9b27e050e | 92 | |
jford38 | 6:3be57cf4bd33 | 93 | void game_init(void) { |
jford38 | 6:3be57cf4bd33 | 94 | |
jford38 | 6:3be57cf4bd33 | 95 | led1 = 0; led2 = 0; led3 = 0; led4 = 0; |
jford38 | 6:3be57cf4bd33 | 96 | |
jford38 | 17:7bc7127782e4 | 97 | pb_u.mode(PullUp); |
jford38 | 6:3be57cf4bd33 | 98 | pb_r.mode(PullUp); |
jford38 | 17:7bc7127782e4 | 99 | pb_d.mode(PullUp); |
jford38 | 17:7bc7127782e4 | 100 | pb_l.mode(PullUp); |
jford38 | 6:3be57cf4bd33 | 101 | |
jford38 | 6:3be57cf4bd33 | 102 | pc.printf("\033[2J\033[0;0H"); // Clear the terminal screen. |
jford38 | 6:3be57cf4bd33 | 103 | pc.printf("I'm alive! Player 1\n"); // Let us know you made it this far. |
jford38 | 7:9506f2d84162 | 104 | int mode = game_menu(); |
jford38 | 17:7bc7127782e4 | 105 | sync.init(&uLCD, &acc, &pb_u, &pb_r, &pb_d, &pb_l, mode); // Connect to the other player. |
jford38 | 10:5da9b27e050e | 106 | map_init(); |
jford38 | 6:3be57cf4bd33 | 107 | pc.printf("Initialized...\n"); // Let us know you finished initializing. |
jford38 | 6:3be57cf4bd33 | 108 | } |
jford38 | 6:3be57cf4bd33 | 109 | |
jford38 | 0:899c85cd266f | 110 | int main (void) { |
jford38 | 17:7bc7127782e4 | 111 | int* p1_inputs; |
jford38 | 17:7bc7127782e4 | 112 | int* p2_inputs; |
jford38 | 8:e6dd05393290 | 113 | |
jford38 | 8:e6dd05393290 | 114 | game_init(); |
jford38 | 8:e6dd05393290 | 115 | |
jford38 | 12:088a8203a9bb | 116 | Tank t1(4, 21, 12, 8, TANK_RED); |
jford38 | 12:088a8203a9bb | 117 | Tank t2(111, 21, 12, 8, TANK_BLUE); |
jford38 | 12:088a8203a9bb | 118 | Bullet b1(&t1); |
jford38 | 12:088a8203a9bb | 119 | Bullet b2(&t2); |
jford38 | 12:088a8203a9bb | 120 | |
jford38 | 5:cfec780c935b | 121 | |
jford38 | 12:088a8203a9bb | 122 | frame_timer.start(); |
jford38 | 0:899c85cd266f | 123 | while(1) { |
jford38 | 12:088a8203a9bb | 124 | |
jford38 | 17:7bc7127782e4 | 125 | sync.set_p1_inputs(); |
jford38 | 17:7bc7127782e4 | 126 | |
jford38 | 17:7bc7127782e4 | 127 | p1_inputs = sync.get_p1_inputs(); |
jford38 | 17:7bc7127782e4 | 128 | p2_inputs = sync.get_p2_inputs(); |
jford38 | 17:7bc7127782e4 | 129 | |
jford38 | 17:7bc7127782e4 | 130 | |
jford38 | 17:7bc7127782e4 | 131 | led1 = p2_inputs[0] ^ p1_inputs[0]; |
jford38 | 17:7bc7127782e4 | 132 | led2 = p2_inputs[1] ^ p1_inputs[1]; |
jford38 | 17:7bc7127782e4 | 133 | led3 = p2_inputs[2] ^ p1_inputs[2]; |
jford38 | 17:7bc7127782e4 | 134 | led4 = p2_inputs[3] ^ p1_inputs[3]; |
jford38 | 8:e6dd05393290 | 135 | |
jford38 | 17:7bc7127782e4 | 136 | float ax1 = (float) p1_inputs[4] / 65536.0; |
jford38 | 17:7bc7127782e4 | 137 | float ay1 = (float) p1_inputs[5] / 65536.0; |
jford38 | 17:7bc7127782e4 | 138 | float az1 = (float) p1_inputs[6] / 65536.0; |
jford38 | 17:7bc7127782e4 | 139 | pc.printf("P1 X: %f\tY: %f\tZ: %f\n", ax1, ay1, az1); |
jford38 | 11:f455e907baba | 140 | |
jford38 | 17:7bc7127782e4 | 141 | float ax2 = (float) p2_inputs[4] / 65536.0; |
jford38 | 17:7bc7127782e4 | 142 | float ay2 = (float) p2_inputs[5] / 65536.0; |
jford38 | 17:7bc7127782e4 | 143 | float az2 = (float) p2_inputs[6] / 65536.0; |
jford38 | 17:7bc7127782e4 | 144 | pc.printf("P2 X: %f\tY: %f\tZ: %f\n", ax2, ay2, az2); |
jford38 | 17:7bc7127782e4 | 145 | |
jford38 | 17:7bc7127782e4 | 146 | /* |
jford38 | 11:f455e907baba | 147 | if(!pb_l) t1.reposition(t1.x-1, t1.y, t1.barrel_theta); |
jford38 | 11:f455e907baba | 148 | if(!pb_r) t1.reposition(t1.x+1, t1.y, t1.barrel_theta); |
jford38 | 17:7bc7127782e4 | 149 | if(p2_inputs[3]) t2.reposition(t2.x-1, t2.y, t2.barrel_theta); |
jford38 | 11:f455e907baba | 150 | if(p2_buttons[1]) t2.reposition(t2.x+1, t2.y, t2.barrel_theta); |
jford38 | 11:f455e907baba | 151 | |
jford38 | 12:088a8203a9bb | 152 | //if(!pb_d) t1.reposition(t1.x, t1.y, t1.barrel_theta-PI/30.0); |
jford38 | 12:088a8203a9bb | 153 | if(!pb_u) t1.reposition(t1.x, t1.y, t1.barrel_theta+PI/30.0); |
jford38 | 11:f455e907baba | 154 | if(p2_buttons[0]) t2.reposition(t2.x, t2.y, t2.barrel_theta+PI/30.0); |
jford38 | 14:36c306e26317 | 155 | //if(p2_buttons[2]) t2.reposition(t2.x, t2.y, t2.barrel_theta-PI/30.0); |
jford38 | 11:f455e907baba | 156 | |
jford38 | 12:088a8203a9bb | 157 | if(!pb_d) { b1.shoot(); } |
jford38 | 14:36c306e26317 | 158 | if(p2_buttons[2]) { b2.shoot(); } |
jford38 | 12:088a8203a9bb | 159 | |
jford38 | 15:4b27a3a95772 | 160 | int retval = b1.time_step(frame_timer.read()); |
jford38 | 15:4b27a3a95772 | 161 | if(retval) { |
jford38 | 15:4b27a3a95772 | 162 | sync.update(); |
jford38 | 15:4b27a3a95772 | 163 | pc.printf("P1 wins!"); |
jford38 | 15:4b27a3a95772 | 164 | break; |
jford38 | 15:4b27a3a95772 | 165 | } |
jford38 | 15:4b27a3a95772 | 166 | retval = b2.time_step(frame_timer.read()); |
jford38 | 15:4b27a3a95772 | 167 | if(retval) { |
jford38 | 15:4b27a3a95772 | 168 | sync.update(); |
jford38 | 15:4b27a3a95772 | 169 | pc.printf("P2 wins!"); |
jford38 | 15:4b27a3a95772 | 170 | break; |
jford38 | 15:4b27a3a95772 | 171 | } |
jford38 | 17:7bc7127782e4 | 172 | */ |
jford38 | 17:7bc7127782e4 | 173 | //frame_timer.reset(); |
jford38 | 11:f455e907baba | 174 | |
jford38 | 12:088a8203a9bb | 175 | sync.update(); |
jford38 | 3:3ddefff03cb2 | 176 | } |
jford38 | 15:4b27a3a95772 | 177 | |
jford38 | 17:7bc7127782e4 | 178 | // This dies after a while, and I have NO IDEA WHY. |
jford38 | 15:4b27a3a95772 | 179 | int i = 0; |
jford38 | 15:4b27a3a95772 | 180 | while(1) { |
jford38 | 15:4b27a3a95772 | 181 | sync.cls(); |
jford38 | 17:7bc7127782e4 | 182 | sync.locate(i, 9); |
jford38 | 17:7bc7127782e4 | 183 | char msg[] = "GAME OVER!"; |
jford38 | 17:7bc7127782e4 | 184 | sync.puts(msg, sizeof(msg)); |
jford38 | 15:4b27a3a95772 | 185 | sync.update(); |
jford38 | 17:7bc7127782e4 | 186 | i = (i+1)%10; |
jford38 | 15:4b27a3a95772 | 187 | wait(0.1); |
jford38 | 15:4b27a3a95772 | 188 | } |
jford38 | 0:899c85cd266f | 189 | } |