
player 1
Dependencies: 4DGL-uLCD-SE PinDetect SparkfunAnalogJoystick mbed-rtos mbed SDFileSystem
Fork of 4180FinalLab by
Wireless 2 Player Pong game
main.cpp
- Committer:
- fepie3
- Date:
- 2016-04-28
- Revision:
- 9:aa967c554d10
- Parent:
- 8:8cc2aa78348c
- Child:
- 10:b57b3fbf8266
File content as of revision 9:aa967c554d10:
#include "mbed.h" #include "rtos.h" #include "PinDetect.h" #include "Speaker.h" #include "soundBuilder.h" #include "SparkfunAnalogJoystick.h" #include "paddle.h" #include "ball.h" // Pushbuttons SparkfunAnalogJoystick joystick(p16, p15, p14); //PinDetect select(p13); //Speaker Speaker mySpeaker(p25); Serial pc(USBTX, USBRX); Serial xbee(p9, p10); //Wifi Huzzah huzzah("fese","12345678", &esp, &pc); Serial esp(p28,p27); DigitalOut reset(p26); int player1score,player2score, highscore1,highscore2; //SD Card Storage SDFileSystem sd(p5, p6, p7, p8, "sd"); // State machine definitions enum gameStateType {START, WAIT, GAME_SETUP, GAME, WIN, LOSE}; /* State Definitions: * START -- Creates the start screen * WAIT -- After the start screen, goes into wait where mbed spins and does nothing * GAME_SETUP -- Sets up one time things (like boarders, initializes beginning velocity * GAME -- When the user actually gets to play * LOSE -- clears the screen, prints you lose, waits, then goes back to start */ // Global state machine variable (So that the select can modify it) gameStateType gameState = START; bool ready = false; Paddle botPaddle(0, 0, 0, 0); Paddle topPaddle(0, 0, 0, 0); Ball ball(0, 0, 0); uint8_t gameLowX = 10, gameHighX = 190, gameLowY = 5, gameHighY = 245, gameX = 200, gameY = 250; uint8_t gameCenterX = gameX/2, gameCenterY = gameY/2; uint8_t ballSize=10; uint8_t paddleWidth = 5, paddleLength = 40; float botMove = joystick.yAxis(); uint8_t botScore = 0; uint8_t topScore = 0; int i = 0; // thread that plays game sounds through the speaker void speaker_thread(void const *argument) { Speaker *player = &mySpeaker; // Start Song float sFreq[] = {550,750,550,750}; float sDur[] = {.3,.3,.3,.3}; float sVol[] = {.01,.01,.01,.01}; SoundBuilder startSong(sFreq, sDur, sVol, sizeof(sFreq)/sizeof(*sFreq), player); // End Song float eFreq[] = {300,200,250,225,200,150,150,100}; float eDur[] = {.3,.3,.3,.3,.3,.3,.3,.3}; float eVol[] = {.01,.01,.01,.01,.01,.01,.01,.01}; SoundBuilder endSong(eFreq, eDur, eVol, sizeof(eFreq)/sizeof(*eFreq), player); while (true) { switch (gameState) { case GAME: // if game is running and user dodges a pipe, play a note if (topPaddle.checkHit(ball.getFutureX(), ball.getFutureY(), ball.getSize()) || botPaddle.checkHit(ball.getFutureX(), ball.getFutureY(), ball.getSize()) || ball.getFutureX() <= 10 || ball.getFutureX() + ball.getSize() >= 190) { mySpeaker.PlayNote(440, 0.1, 0.01); } if (ball.getY() < 5){ mySpeaker.PlayNote(440, 0.1, 0.01); mySpeaker.PlayNote(880, 0.1, 0.01); } else if (ball.getY() + ball.getSize() > 245){ mySpeaker.PlayNote(880, 0.1, 0.01); mySpeaker.PlayNote(440, 0.1, 0.01); } break; case START: // play a song at the start of the game startSong.playSong(); Thread::wait(5000); break; case WIN: // play a song when the player wins the game case LOSE: // play a song when the player loses the game endSong.playSong(); Thread::wait(5000); break; } } } // thread that writes to the sd card and loads highscores to website void sd_card_thread(void const *argument) { while (true) { FILE *fp = fopen("/sd/highscore.txt", "r"); if(fp == NULL) { error("Could not open file for read\n"); } fscanf(fp, "%i%i", &player1score, &player2score); fclose(fp); huzzah.sendwebpage(player1score, player2score); switch (gameState) { case WIN: highscore2=0; //reset player 2 highscore if (player1score < highscore1){ // overwrite previous high score fp = fopen("/sd/highscore.txt", "w"); fprintf(fp, "%i%i", highscore1, player2score); fclose(fp); huzzah.sendwebpage(player1score, player2score); } highscore1++; case LOSE: highscore1=0; //reset player 1 highscore if (player2score < highscore2){ // overwrite previous high score fp = fopen("/sd/highscore.txt", "w"); fprintf(fp, "%i%i", player1score, highscore2); fclose(fp); huzzah.sendwebpage(player1score, player2score); } highscore2++; break; } } } void xbee_thread(void const *argument) { while (true) { switch (gameState) { case WAIT: if (ready && xbee.writeable()) { xbee.putc(1); } if (ready && xbee.readable()) { char c = xbee.getc(); if (c == 1) { gameState = GAME_SETUP; } } break; case GAME: if (xbee.writeable()) { xbee.putc(botPaddle.getX()); } if (xbee.readable()) { char c = xbee.getc(); uint8_t top = 200 - paddleLength - ((uint8_t) c); topPaddle.setX(top); } break; } } } int main() { //WifiServer Configuration and set-up highscore1 = 0; // variable to store high score highscore2=0; reset=0; //hardware reset for 8266 Thread::wait(500); reset=1; esp.baud(9600); huzzah.config(); huzzah.sendwebpage(highscore1,highscore2); // This is setting up the joystick select as a pushbutton //joystick.set_callback(&select_hit_callback); pc.format(8, SerialBase::None, 1); pc.baud(115200); botPaddle = Paddle(gameCenterX-(paddleLength/2), gameHighY, paddleLength, paddleWidth); botPaddle.setLimits(gameLowX, gameHighX); botPaddle.setMaxMove(3); topPaddle = Paddle(gameCenterX-(paddleLength/2), gameLowY, paddleLength, paddleWidth); topPaddle.setLimits(gameLowX, gameHighX); topPaddle.setMaxMove(3); ball = Ball(gameCenterX, gameCenterY, ballSize); ball.setVxDir(true); ball.setVyDir(true); while (!pc.readable()){ } Thread thread1(speaker_thread); Thread thread2(sd_card_thread); Thread thread3(xbee_thread); while (1) { switch (gameState) { case START: if (pc.writeable()){ pc.printf("%c%c%c%c%c", 0, 0, 0, 0, 0); ball.setVxDir(true); ball.setVyDir(true); gameState = WAIT; } break; case GAME_SETUP: ball.reset(gameCenterX-(ballSize/2), gameCenterY-(ballSize/2), 0, 6); botPaddle.reset(gameCenterX-(paddleLength/2), gameHighY); topPaddle.reset(gameCenterX-(paddleLength/2), gameLowY); if (pc.writeable()){ pc.printf("%c%c%c%c%c", 3, botScore, topScore, 0, 0); ready = false; srand(i); gameState = GAME; Thread::wait(2000); } break; case GAME: if (pc.writeable()) { pc.printf("%c%c%c%c%c", 4, botPaddle.getX(), topPaddle.getX(), ball.getX(), ball.getY()); uint8_t size = ball.getSize(); //stored in a temp variable because used a lot if (ball.getFutureX() <= gameLowX){ ball.reverseXDirection(); } else if (ball.getFutureX() + size >= gameHighX){ ball.reverseXDirection(); } if (topPaddle.checkHit(ball.getFutureX(), ball.getFutureY(), size)) { ball.reverseYDirection(); uint8_t fx = ball.getFutureX(); uint8_t newVx = topPaddle.returnAngle(fx, size); uint8_t newVy = 6 - newVx; ball.setVx(newVx); ball.setVy(newVy); ball.setVxDir(topPaddle.returnDir(fx, size)); } else if (botPaddle.checkHit(ball.getFutureX(), ball.getFutureY(), size)) { ball.reverseYDirection(); uint8_t fx = ball.getFutureX(); uint8_t newVx = botPaddle.returnAngle(fx, size); uint8_t newVy = 6 - newVx; ball.setVx(newVx); ball.setVy(newVy); ball.setVxDir(botPaddle.returnDir(fx, size)); } if (ball.getY() < gameLowY){ botScore++; ball.setVyDir(false); gameState = GAME_SETUP; } else if (ball.getY() + size > gameHighY){ topScore++; ball.setVyDir(true); gameState = GAME_SETUP; } if (botScore >= 5) { gameState = WIN; } else if (topScore >= 5) { gameState = LOSE; } ball.update(); botMove = -joystick.yAxis(); if ((botMove < -0.1 || botMove > 0.1) && ball.getY() < gameHighY - 50) { botPaddle.move(botMove); } } break; case LOSE: if (pc.writeable()){ pc.printf("%c%c%c%c%c", 5, 0, 0, 0, 0); botScore = 0; topScore = 0; Thread::wait(5000); gameState = START; } break; case WIN: if (pc.writeable()){ pc.printf("%c%c%c%c%c", 6, 0, 0, 0, 0); botScore = 0; topScore = 0; Thread::wait(5000); gameState = START; } break; case WAIT: if (pc.writeable()){ // Used to seed the rand() function so the ball has a random starting direction i++; if (joystick.button()) ready = true; if (ready){ pc.printf("%c%c%c%c%c", 2, 0, 0, 0, 0); } else { pc.printf("%c%c%c%c%c", 1, 0, 0, 0, 0); } } break; } Thread::wait(20); } }