The classic dueling tanks game for mbed.
Dependencies: 4DGL-uLCD-SE DRV2605 EthernetInterface Game_Synchronizer MMA8452 SDFileSystem SparkfunAnalogJoystick mbed-rtos mbed wave_player
Fork of 2035_Tanks_Shell by
main.cpp
- Committer:
- macenzofan
- Date:
- 2017-03-13
- Revision:
- 28:8dbb85f35be6
- Parent:
- 27:bd55ab4d137c
File content as of revision 28:8dbb85f35be6:
// Student Side. #include "mbed.h" #include "DRV2605.h" #include "SDFileSystem.h" #include "wave_player.h" #include "playSound.h" #include "SparkfunAnalogJoystick.h" #include "game_synchronizer.h" #include "tank.h" #include "bullet.h" #include "globals.h" SparkfunAnalogJoystick joystick(p15, p16, p17); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); DRV2605 haptics(p9, p10); DigitalIn pb_u(p21); // Up Button DigitalIn pb_r(p22); // Right Button DigitalIn pb_d(p23); // Down Button DigitalIn pb_l(p24); // Left Button Serial pc(USBTX, USBRX); // Serial connection to PC. Useful for debugging! MMA8452 acc(p28, p27, 100000); // Accelerometer (SDA, SCL, Baudrate) uLCD_4DGL uLCD(p13,p14,p11); // LCD (tx, rx, reset) SDFileSystem sd(p5, p6, p7, p8, "sd"); // SD (mosi, miso, sck, cs) AnalogOut DACout(p18); // speaker wave_player player(&DACout); // wav player Game_Synchronizer sync(PLAYER1); // Game_Synchronizer (PLAYER) Timer frame_timer; // Timer // Global variables go here. int winner = -1; int whose_turn = PLAYER1; int menu=1; int t2minpixelcolor; int t1maxpixelcolor; int t1y; int t2y; // Ask the user whether to run the game in Single- or Multi-Player mode. // Note that this function uses uLCD instead of sync because it is only // writing to the local (Player1) lcd. Sync hasn't been initialized yet, // so you can't use it anyway. For the same reason, you must access // the buttons directly e.g. if( !pb_r ) { do something; }. // return MULTI_PLAYER if the user selects multi-player. // return SINGLE_PLAYER if the user selects single-player. int game_menu(void) { uLCD.baudrate(BAUD_3000000); // the locate command tells the screen where to place the text. uLCD.filled_rectangle(11,54,117,99,BLACK); uLCD.rectangle(10, 55, 118, 100, WHITE); uLCD.locate(6,8); uLCD.puts("1 Player"); uLCD.locate(6,9); uLCD.puts("2 Player"); uLCD.locate(6,10); uLCD.puts("Settings"); uLCD.color(RED); uLCD.circle(25, 67, 1, RED); uLCD.circle(25, 75, 1, RED); uLCD.circle(25, 83, 1, RED); uLCD.circle(25, 67, 2, WHITE); uLCD.text_width(2); uLCD.text_height(2); uLCD.locate(1,1); uLCD.puts("DUELING"); uLCD.locate(2,2); uLCD.text_bold(TEXTBOLD); uLCD.puts("TANKS"); uLCD.color(WHITE); //playSound("/sd/wavfiles/Dueling Banjo.wav"); while(true){ if (menu==1){ if (!pb_d){ uLCD.circle(25, 67, 2, BLACK); uLCD.circle(25, 75, 2, WHITE); uLCD.circle(25, 83, 2, BLACK); wait(.25); menu=2; } if (!pb_u){ uLCD.circle(25, 67, 2, BLACK); uLCD.circle(25, 75, 2, BLACK); uLCD.circle(25, 83, 2, WHITE); wait(.25); menu=3; } if (!pb_r){ return SINGLE_PLAYER; } } if (menu==2){ if (!pb_d){ uLCD.circle(25, 67, 2, BLACK); uLCD.circle(25, 75, 2, BLACK); uLCD.circle(25, 83, 2, WHITE); wait(.25); menu=3; } if (!pb_u){ uLCD.circle(25, 67, 2, WHITE); uLCD.circle(25, 75, 2, BLACK); uLCD.circle(25, 83, 2, BLACK); wait(.25); menu=1; } if(!pb_r){ return MULTI_PLAYER; } } if (menu==3){ if (!pb_d){ uLCD.circle(25, 67, 2, WHITE); uLCD.circle(25, 75, 2, BLACK); uLCD.circle(25, 83, 2, BLACK); wait(.25); menu=1; } if (!pb_u){ uLCD.circle(25, 67, 2, BLACK); uLCD.circle(25, 75, 2, WHITE); uLCD.circle(25, 83, 2, BLACK); wait(.25); menu=2; } if(!pb_r){ //SETTINGS(); } } } } //wait(10); // Eventually you can take this out. // Eventually you should return SINGLE_PLAYER or MULTI_PLAYER // depending on the user's choice. //return SINGLE_PLAYER; // Initialize the world map. I've provided a basic map here, // but as part of the assignment you must create more // interesting map(s). // Note that calls to sync.function() will run function() // on both players' LCDs (assuming you are in multiplayer mode). // In single player mode, only your lcd will be modified. (Makes sense, right?) void map_init() { // Fill the entire screen with sky blue. sync.background_color(SKY_COLOR); //uLCD.media_init(); //uLCD.set_byte_address(0x00000, 0x3B5001); //uLCD.display_image(64,64); // Call the clear screen function to force the LCD to redraw the screen // with the new background color. sync.cls(); // Draw the ground in green. sync.filled_rectangle(0,0,128,20, GND_COLOR); sync.line(0,20,128,20, TREE); // Draw some obstacles. They don't have to be black, // but they shouldn't be the same color as the sky or your tanks. // Get creative here. You could use brown and grey to draw a mountain // or something cool like that. //sync.triangle(0, 20, 128, 20, 85, 55, BROWN); sync.rectangle(53, 17, 76, 78, BLACK); sync.filled_rectangle(54, 17, 75, 77, WHITE); sync.filled_rectangle(65, 17, 69, 27, BLACK); sync.filled_rectangle(67, 32, 71, 37, BLACK); sync.filled_rectangle(67, 41, 71, 46, BLACK); sync.filled_rectangle(67, 50, 71, 55, BLACK); sync.filled_rectangle(67, 59, 71, 64, BLACK); sync.filled_rectangle(67, 68, 71, 73, BLACK); sync.filled_rectangle(58, 32, 62, 37, BLACK); sync.filled_rectangle(58, 41, 62, 46, BLACK); sync.filled_rectangle(58, 50, 62, 55, BLACK); sync.filled_rectangle(58, 59, 62, 64, BLACK); sync.filled_rectangle(58, 68, 62, 73, BLACK); sync.filled_rectangle(52, 16, 54, 20, BROWN); sync.update(); sync.filled_circle(53, 26, 6, TREE); sync.filled_circle(78, 19, 4, TREE); sync.filled_circle(1, 12, 7, TREE); sync.filled_circle(6, 10, 4, TREE); sync.filled_circle(9, 10, 4, TREE); sync.filled_circle(14, 10, 2, TREE); sync.filled_circle(100, 12, 7, TREE); sync.circle(100, 12, 7, SHRUB); sync.filled_circle(106, 10, 4, TREE); sync.filled_circle(90, 10, 4, TREE); sync.filled_circle(110, 10, 2, TREE); sync.circle(1, 12, 7, SHRUB); sync.filled_circle(115, 115, 10, YELLOW); sync.circle(115, 115, 10, ORANGE); // Before you write text on the screens, tell the LCD where to put it. sync.locate(6,15); // Set the text background color to match the sky. Just for looks. sync.textbackground_color(SKY_COLOR); // Display the game title. char title[] = "ROUND 1\n GO!"; sync.puts(title, sizeof(title)); // Flush the draw buffer and execute all the accumulated draw commands. sync.update(); playSound("/sd/wavfiles/boxingbell.wav"); sync.filled_rectangle(25, 122, 100, 128, SKY_COLOR); sync.update(); wait(1); sync.filled_rectangle(45, 114, 75, 122, SKY_COLOR); } // Initialize the game hardware. // Call game_menu to find out which mode to play the game in (Single- or Multi-Player) // Initialize the game synchronizer. void game_init(void) { led1 = 0; led2 = 0; led3 = 0; led4 = 0; pb_u.mode(PullUp); pb_r.mode(PullUp); pb_d.mode(PullUp); pb_l.mode(PullUp); pc.printf("\033[2J\033[0;0H"); // Clear the terminal screen. pc.printf("I'm alive! Player 1\n"); // Let us know you made it this far. int mode = game_menu(); sync.init(&uLCD, &acc, &pb_u, &pb_r, &pb_d, &pb_l, mode); // Connect to the other player. map_init(); pc.printf("Initialized...\n"); // Let us know you finished initializing. } // Display some kind of game over screen which lets us know who won. // Play a cool sound! void game_over(); int main (void) { int* p1_buttons; int* p2_buttons; int p1lives=2; int p2lives=2; int i=0; float ax1, ay1, az1; float ax2, ay2, az2; ax1 = 0.0f; ay1 = 0.0f; ax2 = 0.0f; ay2 = 0.0f; game_init(); // Create your tanks. Tank t1(4, 22, 16, 6, TANK_RED); // (min_x, min_y, width, height, color) Tank t2(108, 22, 16, 6, TANK_BLUE); // (min_x, min_y, width, height, color) // For each tank, create a bullet. Bullet b1(&t1); Bullet b2(&t2); //Bouncy b3(&t1); //Bouncy b4(&t2); frame_timer.start(); // Your code starts here... while(true) { t1y=t1.min_y(); t2y=t2.min_y(); t2minpixelcolor=sync.read_pixel(t2.min_x()-5,t2y); t1maxpixelcolor=sync.read_pixel(t1.max_x()+1,t1y); // Get a pointer to the buttons for both sides. // From now on, you can access the buttons for player x using // // px_buttons[U_BUTTON] // px_buttons[R_BUTTON] // px_buttons[D_BUTTON] // px_buttons[L_BUTTON] p1_buttons = sync.get_p1_buttons(); p2_buttons = sync.get_p2_buttons(); led1 = p1_buttons[0] ^ p2_buttons[0]; led2 = p1_buttons[1] ^ p2_buttons[1]; led3 = p1_buttons[2] ^ p2_buttons[2]; led4 = p1_buttons[3] ^ p2_buttons[3]; // Get the accelerometer values. sync.get_p1_accel_data(&ax1, &ay1, &az1); sync.get_p2_accel_data(&ax2, &ay2, &az2); //ay1 = joystick.xAxis()*2 -1; ax1 = -joystick.yAxis(); //ay2 = joystick.xAxis()*2 -1; ax2 = -joystick.yAxis(); int pix1=sync.read_pixel(64,30); int pix2=sync.read_pixel(64,39); int pix3=sync.read_pixel(64,48); int pix4=sync.read_pixel(64,57); int pix5=sync.read_pixel(64,66); int j; //Building collapse animation: if(sync.pixel_eq(pix5,SKY_COLOR)==1){ //If highest test point is hit, do the following for loop. for(j=0;j<10;j++){ sync.filled_rectangle(53, 78-j, 76, 80-j, SKY_COLOR); sync.line(53, 77-j, 76, 79-j, BLACK); sync.filled_rectangle(54, 74-j, 75, 77-j, WHITE); sync.filled_circle(53, 64,6, LT_GREY); sync.filled_circle(76, 64,5, LT_GREY); sync.filled_circle(56, 64,4, MED_GREY); sync.filled_circle(73, 64,4, DRK_GREY); //playSound("/sd/wavfiles/colapse.wav"); haptics.play_waveform(1); sync.filled_circle(70, 64,5, MED_GREY); sync.filled_circle(64, 64,6, LT_GREY); sync.update(); sync.filled_circle(52,65,6,SKY_COLOR); sync.filled_circle(77,65,6,SKY_COLOR); sync.filled_circle(52,65,6,SKY_COLOR); sync.filled_circle(55,65,6,SKY_COLOR); sync.filled_circle(70,69,6,SKY_COLOR); sync.filled_circle(76,67,6,SKY_COLOR); sync.filled_circle(65,65,6,SKY_COLOR); sync.filled_circle(64,66,3,PIX); //playSound("/sd/wavfiles/colapse.wav"); haptics.play_waveform(1); } } if(sync.pixel_eq(pix4,SKY_COLOR)==1){ //If the second highest point is hit, do the following for loop. for(j=0;j<20;j++){ sync.filled_rectangle(53, 78-j, 76, 80-j, SKY_COLOR); sync.line(53, 77-j, 76, 79-j, BLACK); sync.filled_rectangle(54, 74-j, 75, 77-j, WHITE); sync.filled_circle(53, 54,6, LT_GREY); sync.filled_circle(76, 54,5, LT_GREY); sync.filled_circle(56, 54,4, MED_GREY); sync.filled_circle(73, 54,4, DRK_GREY); //playSound("/sd/wavfiles/colapse.wav"); haptics.play_waveform(1); sync.filled_circle(70, 54,5, MED_GREY); sync.filled_circle(64, 54,6, LT_GREY); sync.update(); sync.filled_circle(52,55,6,SKY_COLOR); sync.filled_circle(77,55,6,SKY_COLOR); sync.filled_circle(52,55,6,SKY_COLOR); sync.filled_circle(60,55,6,SKY_COLOR); sync.filled_circle(70,59,6,SKY_COLOR); sync.filled_circle(76,57,6,SKY_COLOR); sync.filled_circle(65,55,6,SKY_COLOR); sync.filled_circle(64,56,3,PIX); sync.filled_circle(64,66,3,PIX); //playSound("/sd/wavfiles/colapse.wav"); haptics.play_waveform(1); } } if(sync.pixel_eq(pix3,SKY_COLOR)==1){ //If the third highest point is hit, do the following for loop. for(j=0;j<30;j++){ sync.filled_rectangle(53, 78-j, 76, 80-j, SKY_COLOR); sync.line(53, 77-j, 76, 79-j, BLACK); sync.filled_rectangle(54, 74-j, 75, 77-j, WHITE); sync.filled_circle(53, 44,6, LT_GREY); sync.filled_circle(76, 44,5, LT_GREY); haptics.play_waveform(1); sync.update(); sync.filled_circle(56, 44,4, MED_GREY); sync.filled_circle(73, 44,4, DRK_GREY); //playSound("/sd/wavfiles/colapse.wav"); sync.filled_circle(70, 44,5, MED_GREY); sync.filled_circle(64, 44,6, LT_GREY); sync.update(); sync.filled_circle(52,45,6,SKY_COLOR); sync.filled_circle(77,45,6,SKY_COLOR); sync.filled_circle(52,45,6,SKY_COLOR); sync.filled_circle(60,45,6,SKY_COLOR); //playSound("/sd/wavfiles/colapse.wav"); sync.filled_circle(70,49,6,SKY_COLOR); sync.filled_circle(76,47,6,SKY_COLOR); sync.filled_circle(65,45,6,SKY_COLOR); sync.update(); haptics.play_waveform(1); sync.filled_circle(64,46,3,PIX); sync.filled_circle(64,56,3,PIX); sync.filled_circle(64,66,3,PIX); //wait(.5); haptics.play_waveform(1); } } if(sync.pixel_eq(pix2,SKY_COLOR)==1){ //If the lowest test point is hit, do the following for loop. for(j=0;j<40;j++){ sync.filled_rectangle(53, 78-j, 76, 80-j, SKY_COLOR); sync.line(53, 77-j, 76, 79-j, BLACK); sync.filled_rectangle(54, 74-j, 75, 77-j, WHITE); sync.filled_circle(53, 34,6, LT_GREY); sync.filled_circle(76, 34,5, LT_GREY); sync.update(); sync.filled_circle(56, 34,4, MED_GREY); sync.filled_circle(73, 34,4, DRK_GREY); sync.filled_circle(70, 34,5, MED_GREY); sync.filled_circle(64, 34,6, LT_GREY); sync.update(); sync.filled_circle(52,35,6,SKY_COLOR); sync.filled_circle(77,35,6,SKY_COLOR); sync.filled_circle(52,35,6,SKY_COLOR); sync.filled_circle(60,35,6,SKY_COLOR); sync.filled_circle(70,39,6,SKY_COLOR); sync.filled_circle(76,37,6,SKY_COLOR); sync.filled_circle(65,35,6,SKY_COLOR); haptics.play_waveform(1); sync.update(); sync.filled_circle(64,36,3,PIX); sync.filled_circle(64,46,3,PIX); sync.filled_circle(64,56,3,PIX); sync.filled_circle(64,66,3,PIX); haptics.play_waveform(1); } } if(whose_turn == PLAYER1) { //Draw the initial lives for player one and light up tank color to indicate turn sync.rectangle(45, 2, 84, 7, BLACK); if(p1lives==0){ sync.filled_circle(4, 4, 2, TANK_RED); } if(p1lives==1){ sync.filled_circle(10, 4, 2, TANK_RED); sync.filled_circle(4, 4, 2, TANK_RED); } if(p1lives==2){ sync.filled_circle(10, 4, 2, TANK_RED); sync.filled_circle(4, 4, 2, TANK_RED); sync.filled_circle(16, 4, 2, TANK_RED); } //show light blue for player two showing its player ones turn. if(p2lives==0){ sync.filled_circle(124, 4, 2, LT_BLUE); } if(p2lives==1){ sync.filled_circle(118, 4, 2, LT_BLUE); sync.filled_circle(124, 4, 2, LT_BLUE); } if(p2lives==2){ sync.filled_circle(118, 4, 2, LT_BLUE); sync.filled_circle(112, 4, 2, LT_BLUE); sync.filled_circle(124, 4, 2, LT_BLUE); } // Accelerometer example if(ax1 < -ACC_THRESHOLD && sync.pixel_eq(t1maxpixelcolor,SKY_COLOR)==1) { // Move the tank to the right if the accelerometer is tipped far enough to the right. t1.reposition(+1, 0, 0); } if(ax1 < -1.5*ACC_THRESHOLD && sync.pixel_eq(t1maxpixelcolor,SKY_COLOR)==1) { // Move the tank to the right if the accelerometer is tipped far enough to the right. t1.reposition(+3, 0, 0); } if(ax1 > ACC_THRESHOLD && t1.min_x()>0) { // Move the tank to the left if the accelerometer is tipped far enough to the left. t1.reposition(-1, 0, 0); } if(ax1 > 1.5*ACC_THRESHOLD && t1.min_x()>0) { // Move the tank to the left if the accelerometer is tipped far enough to the left. t1.reposition(-3, 0, 0); } if(ay1 > ACC_THRESHOLD) { //Move the barrel up. t1.reposition(0, 0, PI/24); } if(ay1 < -ACC_THRESHOLD) { //Move the barrel down. t1.reposition(0, 0, -PI/24); } // Button example //if(p1_buttons[L_BUTTON]) { // b1.shoot(); //} // hold down left button to power up the power bar. if(p1_buttons[L_BUTTON]){ b1.speed+=3; i+=2; sync.filled_rectangle(46, 3, 45+i, 6, TANK_RED); haptics.play_waveform(1); sync.update(); if(i>=38){ i=37; b1.speed=56; } } else{ i=0; } //Press right button to fire. if(p1_buttons[R_BUTTON]){ b1.shoot(); playSound("/sd/wavfiles/Fire.wav"); haptics.play_waveform(1); b1.speed=0; sync.filled_rectangle(46, 3, 83, 6, GND_COLOR); sync.rectangle(45, 2, 84, 7, BLACK); } //if(p1_buttons[U_BUTTON]){ // sync.filled_circle(24,9,2,BLACK); // bouncy=1; //} float dt = frame_timer.read(); int intersection_code = b1.time_step(dt); if(intersection_code != BULLET_NO_COLLISION || intersection_code == BULLET_OFF_SCREEN) { pc.printf("Now it's P2's turn!\n"); whose_turn = PLAYER2; } // If you shot yourself, you lost a life. if(sync.pixel_eq(intersection_code, t1.tank_color)) { if(p1lives==0){ sync.filled_circle(4, 4, 2, GND_COLOR); sync.update(); // Is this necessary? winner = PLAYER2; //game_over(); break; } else if(p1lives!=0){ if(p1lives==1){ p1lives+=-1; sync.filled_circle(10, 4, 2, GND_COLOR); } if(p1lives==2){ p1lives+=-1; sync.update(); sync.filled_circle(16, 4, 2, GND_COLOR); } } } // If you shot the other guy, you took one life! if(sync.pixel_eq(intersection_code, t2.tank_color)) { if(p2lives==0){ sync.filled_circle(124, 4, 2, GND_COLOR); sync.update(); // Is this necessary? winner = PLAYER1; break; } else if(p2lives!=0){ if(p2lives==1){ p2lives+=-1; sync.filled_circle(118, 4, 2, GND_COLOR); } if(p2lives==2){ p2lives+=-1; sync.update(); sync.filled_circle(112, 4, 2, GND_COLOR); } } } } else if(whose_turn == PLAYER2) { // Show player two's lives in tank color and player ones in light red. if(p2lives==0){ sync.filled_circle(124, 4, 2, TANK_BLUE); } if(p2lives==1){ sync.filled_circle(118, 4, 2, TANK_BLUE); sync.filled_circle(124, 4, 2, TANK_BLUE); } if(p2lives==2){ sync.filled_circle(118, 4, 2, TANK_BLUE); sync.filled_circle(112, 4, 2, TANK_BLUE); sync.filled_circle(124, 4, 2, TANK_BLUE); } if(p1lives==0){ sync.filled_circle(4, 4, 2, LT_RED); } if(p1lives==1){ sync.filled_circle(10, 4, 2, LT_RED); sync.filled_circle(4, 4, 2, LT_RED); } if(p1lives==2){ sync.filled_circle(10, 4, 2, LT_RED); sync.filled_circle(4, 4, 2, LT_RED); sync.filled_circle(16, 4, 2, LT_RED); } // Accelerometer example if(sync.play_mode==SINGLE_PLAYER){ if(ax1 < -ACC_THRESHOLD && t2.max_x()<127) { // Move the tank to the right if the accelerometer is tipped far enough to the right. t2.reposition(+1, 0, 0); } if(ax1 < -1.5*ACC_THRESHOLD && t2.max_x()<127) { // Move the tank to the right if the accelerometer is tipped far enough to the right. t2.reposition(+3, 0, 0); } if(ax1 > ACC_THRESHOLD && sync.pixel_eq(t2minpixelcolor,SKY_COLOR)==1) { // Move the tank to the left if the accelerometer is tipped far enough to the left. t2.reposition(-1, 0, 0); } if(ax1 > 1.5*ACC_THRESHOLD && sync.pixel_eq(t2minpixelcolor,SKY_COLOR)==1) { // Move the tank to the left if the accelerometer is tipped far enough to the left. t2.reposition(-3, 0, 0); } if(ay1 > ACC_THRESHOLD) { //Move the barrel up. t2.reposition(0, 0, PI/24); } if(ay1 < -ACC_THRESHOLD) { //Move the barrel down. t2.reposition(0, 0, -PI/24); } } if(sync.play_mode==MULTI_PLAYER){ if(ax2 < -ACC_THRESHOLD && t2.max_x()<127) { // Move the tank to the right if the accelerometer is tipped far enough to the right. t2.reposition(+1, 0, 0); } if(ax2 < -1.5*ACC_THRESHOLD && t2.max_x()<127) { // Move the tank to the right if the accelerometer is tipped far enough to the right. t2.reposition(+3, 0, 0); } if(ax2 > ACC_THRESHOLD && sync.pixel_eq(t2minpixelcolor,SKY_COLOR)==1) { // Move the tank to the left if the accelerometer is tipped far enough to the left. t2.reposition(-1, 0, 0); } if(ax2 > 1.5*ACC_THRESHOLD && sync.pixel_eq(t2minpixelcolor,SKY_COLOR)==1) { // Move the tank to the left if the accelerometer is tipped far enough to the left. t2.reposition(-3, 0, 0); } if(ay2 > ACC_THRESHOLD) { //Move the barrel up. t2.reposition(0, 0, PI/24); } if(ay2 < -ACC_THRESHOLD) { //Move the barrel down. t2.reposition(0, 0, -PI/24); } } //If in single player mode charge the power bar. if(sync.play_mode==SINGLE_PLAYER){ if(p1_buttons[L_BUTTON]){ b2.speed+=3; i+=2; sync.filled_rectangle(83, 3, 85-i, 6, TANK_BLUE); haptics.play_waveform(1); if(i>=38){ i=37; b2.speed=56; } } else{ i=0; } // fire tank. if(p1_buttons[R_BUTTON]){ b2.shoot(); playSound("/sd/wavfiles/Fire.wav"); haptics.play_waveform(1); b2.speed=0; sync.filled_rectangle(46, 3, 83, 6, GND_COLOR); sync.rectangle(45, 2, 84, 7, BLACK); } } if(sync.play_mode==MULTI_PLAYER){ if(p2_buttons[L_BUTTON]){ b2.speed+=3; i+=2; sync.filled_rectangle(83, 3, 85-i, 6, TANK_BLUE); sync.update(); if(i>=38){ i=37; b2.speed=56; } } else{ i=0; } if(p2_buttons[R_BUTTON]){ b2.shoot(); playSound("/sd/wavfiles/Fire.wav"); haptics.play_waveform(1); b2.speed=0; sync.filled_rectangle(46, 3, 83, 6, GND_COLOR); sync.rectangle(45, 2, 84, 7, BLACK); } } float dt = frame_timer.read(); int intersection_code = b2.time_step(dt); if(intersection_code != BULLET_NO_COLLISION || intersection_code == BULLET_OFF_SCREEN) { pc.printf("Now it's P2's turn!\n"); whose_turn = PLAYER1; } // If you shot yourself, you lost a life. if(sync.pixel_eq(intersection_code, t1.tank_color)) { if(p1lives==0){ sync.update(); // Is this necessary? winner = PLAYER2; sync.filled_circle(4, 4, 2, GND_COLOR); break; } else if(p1lives!=0){ if(p1lives==1){ p1lives+=-1; sync.filled_circle(10, 4, 2, GND_COLOR); } if(p1lives==2){ p1lives+=-1; sync.filled_circle(16, 4, 2, GND_COLOR); sync.update(); } } // If you shot the other guy, took a life! if(sync.pixel_eq(intersection_code, t2.tank_color)) { if(p2lives==0){ sync.update(); // Is this necessary? winner = PLAYER1; sync.filled_circle(124, 4, 2, GND_COLOR); break; } else if(p2lives!=0){ if(p2lives==1){ p2lives+=-1; sync.filled_circle(118, 4, 2, GND_COLOR); } if(p2lives==2){ p2lives+=-1; sync.filled_circle(112, 4, 2, GND_COLOR); sync.update(); } } } } } frame_timer.reset(); sync.update(); } game_over(); } void game_over() { if(winner==PLAYER1){ char status[]= "GAME OVER!"; char player[]="Player 1 \n wins!"; char play[]="Play again? \n\n Yes No"; sync.rectangle(13,56,115,99,BLACK); sync.filled_rectangle(15,58,113,97,TANK_RED); sync.textbackground_color(TANK_RED); sync.locate(4,10); sync.puts(status, sizeof(status)); sync.update(); wait(2); sync.filled_rectangle(15,62,113,97,TANK_RED); sync.locate(5,10); sync.puts(player, sizeof(player)); sync.update(); playSound("/sd/wavfiles/cheering.wav"); sync.filled_rectangle(15,62,113,97,TANK_RED); sync.locate(4,10); sync.puts(play, sizeof(play)); sync.update(); while(2){ if(!pb_l){ sync.rectangle(33,63,60,76,WHITE); sync.update(); wait(2); sync.cls(); sync.textbackground_color(BLACK); sync.filled_rectangle(0,0,128,128,BLACK); sync.update(); game_init(); } else if(!pb_r){ sync.rectangle(68,63,95,76,WHITE); sync.update(); wait(2); sync.cls(); sync.textbackground_color(BLACK); sync.filled_rectangle(0,0,128,128,BLACK); sync.update(); main(); } } } if(winner==PLAYER2){ char status[]= "GAME OVER!"; char player[]="Player 2 \n wins!"; char play[]="Play again? \n\n Yes No"; sync.rectangle(13,56,115,99,BLACK); sync.filled_rectangle(15,58,113,97,TANK_BLUE); sync.textbackground_color(TANK_BLUE); sync.locate(4,10); sync.puts(status, sizeof(status)); sync.update(); wait(2); sync.filled_rectangle(15,62,113,97,TANK_BLUE); sync.locate(5,10); sync.puts(player, sizeof(player)); sync.update(); playSound("/sd/wavfiles/cheering.wav"); sync.filled_rectangle(15,62,113,97,TANK_BLUE); sync.locate(4,10); sync.puts(play, sizeof(play)); sync.update(); while(true){ if(!pb_l){ sync.rectangle(33,63,60,76,WHITE); sync.update(); wait(2); sync.cls(); sync.textbackground_color(BLACK); sync.filled_rectangle(0,0,128,128,BLACK); sync.update(); game_init(); } else if(!pb_r){ sync.rectangle(68,63,95,76,WHITE); sync.update(); wait(2); sync.cls(); sync.textbackground_color(BLACK); sync.filled_rectangle(0,0,128,128,BLACK); sync.update(); main(); } } } }