Game for 4180 Lab4
Dependencies: 4DGL-uLCD-SE 4180_lab4_tank_war_game Game_Synchronizer MMA8452 SDFileSystem mbed-rtos mbed wave_player
Dependents: 4180_lab4_tank_war_game
main.cpp
- Committer:
- ychen644
- Date:
- 2017-03-13
- Revision:
- 0:ffed9a3bc797
File content as of revision 0:ffed9a3bc797:
// Student Side. #include "mbed.h" #include "SDFileSystem.h" #include "wave_player.h" #include "game_synchronizer.h" #include "tank.h" #include "bullet.h" #include "globals.h" #include "playSound.h" DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); 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(p9, p10, 100000); // Accelerometer (SDA, SCL, Baudrate) uLCD_4DGL uLCD(p28,p27,p29); // 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 p1score = 0; int p2score = 0; int skyChange = 0; int SKY_COLOR = 0x7EC0EE; int SKY_COLOR2 = 0x0033cc; // 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. FILE *wave_file; int game_menu(void) { uLCD.baudrate(BAUD_3000000); // the locate command tells the screen where to place the text. uLCD.cls(); uLCD.locate(2,2); uLCD.puts("Press Left for"); uLCD.locate(2,3); uLCD.puts("Single Player"); uLCD.locate(2,5); uLCD.puts("Press Right for"); uLCD.locate(2,6); uLCD.puts("Multi-Player"); // Button Example: // Use !pb_r to access the player1 right button value. // Eventually you should return SINGLE_PLAYER or MULTI_PLAYER // depending on the user's choice. while(true) { if (!pb_l) { uLCD.cls(); uLCD.locate(2,2); uLCD.puts("Press Up"); uLCD.locate(2,3); uLCD.puts("For nighttime."); uLCD.locate(2,5); uLCD.puts("Press Down"); uLCD.locate(2,6); uLCD.puts("For daytime."); while(true) { if (!pb_u) { skyChange = 1; SKY_COLOR = SKY_COLOR2; return SINGLE_PLAYER; } if (!pb_d) { return SINGLE_PLAYER; } } } if (!pb_r) { uLCD.cls(); uLCD.locate(2,2); uLCD.puts("Press Up"); uLCD.locate(2,3); uLCD.puts("For nighttime."); uLCD.locate(2,5); uLCD.puts("Press Down"); uLCD.locate(2,6); uLCD.puts("For daytime."); while(true) { if (!pb_u) { skyChange = 1; SKY_COLOR = SKY_COLOR2; return MULTI_PLAYER; } if (!pb_d) { return MULTI_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); // 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); // 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.filled_rectangle(40, 40, 45, 90, AQUA); sync.filled_rectangle(50, 30, 55, 70, PURPLE); sync.filled_rectangle(59, 20, 69, 60, BLACK); sync.filled_rectangle(74, 30, 79, 70, PURPLE); sync.filled_rectangle(84, 40, 89, 90, AQUA); // Before you write text on the screens, tell the LCD where to put it. sync.locate(0,15); // Set the text background color to match the sky. Just for looks. sync.textbackground_color(SKY_COLOR); // Display the game title. char title[] = " Tanks"; sync.puts(title, sizeof(title)); // Flush the draw buffer and execute all the accumulated draw commands. sync.update(); } // 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); int mode = game_menu(); sync.init(&uLCD, &acc, &pb_u, &pb_r, &pb_d, &pb_l, mode); // Connect to the other player. map_init(); } // Display some kind of game over screen which lets us know who won. // Play a cool sound! int game_over() { int i = 0; playSound("/sd/wavfiles/cheering.wav"); // score keeping char* toPrint1 = new char [7]; char* toPrint2 = new char [7]; toPrint1[6] = '\0'; toPrint2[6] = '\0'; sprintf(&toPrint1[0], "P1: %d", p1score); sprintf(&toPrint2[0], "P2: %d", p2score); while(1) { sync.cls(); // animated winning screen sync.locate(i + 2, 10); if (winner == PLAYER1) { sync.puts("P1 WINS!\n", sizeof("P1 WINS!\n")); } else if (winner == PLAYER2) { sync.puts("P2 WINS!\n", sizeof("P2 WINS!\n")); } sync.locate(2, 8); sync.puts(toPrint1, 8); sync.locate(9, 8); sync.puts(toPrint2, 8); sync.locate(2, 6); sync.puts("Press up to\n", sizeof("Press up to\n")); sync.locate(2, 5); sync.puts("continue!\n", sizeof("continue!\n")); sync.update(); (++i) %= 7; wait(0.1); // restart the game if up is pressed if (!pb_u) { return 1; } } } void menuSound(void const *argument) { FILE *wf; wf=fopen("/sd/wavfiles/applause.wav","r"); player.play(wf); fclose(wf); } int main (void) { int* p1_buttons; int* p2_buttons; float ax1, ay1, az1; float ax2, ay2, az2; // play menu sound Thread thread1(menuSound); game_init(); int restart = 1; while (restart == 1) { map_init(); // Create your tanks. Tank t1(4, 21, 12, 8, TANK_RED); // (min_x, min_y, width, height, color) Tank t2(111, 21, 12, 8, TANK_BLUE); // (min_x, min_y, width, height, color) // For each tank, create a bullet. Bullet b1(&t1); Bullet b2(&t2); // change skycolor t1.changeSky(SKY_COLOR); t2.changeSky(SKY_COLOR); b1.changeSky(SKY_COLOR); b2.changeSky(SKY_COLOR); // reset these values at the start of every round restart = 0; whose_turn = PLAYER1; frame_timer.start(); // Your code starts here... while(true) { // 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); if(whose_turn == PLAYER1) { // delete old triangle on the other player sync.triangle(118, 120, 118, 125, 123, 120, SKY_COLOR); // triangle above player's turn sync.triangle(5, 120, 5, 125, 10, 120, GREEN); sync.update(); // Accelerometer if(ax1 > ACC_THRESHOLD) { // left t1.reposition(-1, 0, 0); } else if(ax1 < -1 * ACC_THRESHOLD) { //right t1.reposition(+1, 0, 0); } if(ay1 > ACC_THRESHOLD) { // up t1.reposition(0, 0, +1); } else if(ay1 < -1 * ACC_THRESHOLD) { // down t1.reposition(0, 0, -1); } // power up button if(p1_buttons[U_BUTTON]) { b1.powerUp(); } // shoot button if(p1_buttons[D_BUTTON]) { b1.shoot(); } float dt = frame_timer.read(); int intersection_code = b1.time_step(dt); // If you shot yourself, you lost. if(sync.pixel_eq(intersection_code, t1.tank_color)) { sync.update(); // Is this necessary? winner = PLAYER2; p2score = p2score + 1; break; } // If you shot the other guy, you won! if(sync.pixel_eq(intersection_code, t2.tank_color)) { sync.update(); winner = PLAYER1; p1score = p1score + 1; break; } // keep playing if(intersection_code != BULLET_NO_COLLISION || intersection_code == BULLET_OFF_SCREEN) { whose_turn = PLAYER2; } } else if(whose_turn == PLAYER2) { // I gave you a lot of the logic for Player1. It's up to you to figure out Player2! // If you are in SINGLE_PLAYER mode, you should use the p1 inputs to control p2. // In MULTI_PLAYER mode, you should use the p2 inputs to control p2. // // Hint: // sync.play_mode will tell you if you are in MULTI_PLAYER or SINGLE_PLAYER mode. // // deletes triangle above other player sync.triangle(5, 120, 5, 125, 10, 120, SKY_COLOR); // triangle above player's turn sync.triangle(118, 120, 118, 125, 123, 120, GREEN); sync.update(); if (sync.play_mode == SINGLE_PLAYER) { if(ax1 > ACC_THRESHOLD) { // left t2.reposition(-1, 0, 0); } else if(ax1 < -1 * ACC_THRESHOLD) { //right t2.reposition(+1, 0, 0); } if(ay1 > ACC_THRESHOLD) { // up t2.reposition(0, 0, +1); } else if(ay1 < -1 * ACC_THRESHOLD) { // down t2.reposition(0, 0, -1); } // powerup button if(p1_buttons[U_BUTTON]) { b2.powerUp(); } // shoot button if(p1_buttons[D_BUTTON]) { b2.shoot(); } } else if (sync.play_mode == MULTI_PLAYER) { if(ax2 > ACC_THRESHOLD) { // left t2.reposition(+1, 0, 0); } else if(ax2 < -1 * ACC_THRESHOLD) { //right t2.reposition(-1, 0, 0); } if(ay2 > ACC_THRESHOLD) { // up t2.reposition(0, 0, +1); } else if(ay2 < -1 * ACC_THRESHOLD) { // down t2.reposition(0, 0, -1); } // powerup button if(p2_buttons[U_BUTTON]) { b2.powerUp(); } // shoot button if(p2_buttons[D_BUTTON]) { b2.shoot(); } } float dt = frame_timer.read(); int intersection_code = b2.time_step(dt); // If you shot yourself, you lost. if(sync.pixel_eq(intersection_code, t2.tank_color)) { sync.update(); // Is this necessary? winner = PLAYER1; p1score = p1score + 1; break; } // If you shot the other guy, you won! if(sync.pixel_eq(intersection_code, t1.tank_color)) { sync.update(); winner = PLAYER2; p2score = p2score + 1; break; } // keep playing if(intersection_code != BULLET_NO_COLLISION || intersection_code == BULLET_OFF_SCREEN) { whose_turn = PLAYER1; } } frame_timer.reset(); sync.update(); } restart = game_over(); } }