player 1

Dependencies:   4DGL-uLCD-SE PinDetect SparkfunAnalogJoystick mbed-rtos mbed SDFileSystem

Fork of 4180FinalLab by Rishi Bhargava

Wireless 2 Player Pong game

Revision:
4:7da18e3c590b
Parent:
3:591086e44bf9
Child:
6:9cdde66d7502
--- a/main.cpp	Sun Apr 24 01:23:28 2016 +0000
+++ b/main.cpp	Tue Apr 26 18:24:46 2016 +0000
@@ -1,14 +1,17 @@
 #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
-AnalogIn xMove(p15); 
-PinDetect select(p13);
+SparkfunAnalogJoystick joystick(p16, p15, p14);
+//PinDetect select(p13);
 //Speaker
-//Speaker mySpeaker(p20);
+Speaker mySpeaker(p25);
 Serial pc(USBTX, USBRX);
  
 // State machine definitions
@@ -25,147 +28,212 @@
 gameStateType gameState = START;
 bool ready = false;
 
-// Pushbutton callbacks for selecting to start game
-void select_hit_callback (void)
-{
-    switch (gameState)
-    {
-    case WAIT:
-        ready = true;
-        break;
+Paddle botPaddle(0, 0, 0, 0);
+Paddle topPaddle(0, 0, 0, 0);
+Ball ball(0, 0, 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;
+        }
     }
 }
  
 int main() 
 {   
     // This is setting up the joystick select as a pushbutton
-    select.mode(PullUp);
-    wait(0.1);
-    select.attach_deasserted(&select_hit_callback);
-    select.setSampleFrequency();
+    //joystick.set_callback(&select_hit_callback);
     
-    pc.baud(9600);
+    pc.format(8, SerialBase::None, 1);
+    pc.baud(115200);
 
     uint8_t gameLowX = 10, gameHighX = 190, gameLowY = 5, gameHighY = 245;
     uint8_t gameCenterX = (gameHighX-gameLowX)/2, gameCenterY = (gameHighY-gameLowY)/2;
     uint8_t ballSize=10;
     uint8_t paddleWidth = 5, paddleLength = 35;
-    float botMove = xMove;
-    uint8_t score = 0;
+    float botMove = joystick.yAxis();
+    uint8_t botScore = 0;
+    uint8_t topScore = 0;
     int i = 0;
 
-    Paddle botPaddle(gameCenterX-(paddleLength/2), gameHighY, paddleLength, paddleWidth);
+    botPaddle = Paddle(gameCenterX-(paddleLength/2), gameHighY, paddleLength, paddleWidth);
     botPaddle.setLimits(gameLowX, gameHighX);
     botPaddle.setMaxMove(2);
-    Paddle topPaddle(gameCenterX-(paddleLength/2), gameLowY, paddleLength, paddleWidth);
+    topPaddle = Paddle(gameCenterX-(paddleLength/2), gameLowY, paddleLength, paddleWidth);
     topPaddle.setLimits(gameLowX, gameHighX);
     topPaddle.setMaxMove(2);
-    Ball ball(gameCenterX, gameCenterY, ballSize);
+    ball = Ball(gameCenterX, gameCenterY, ballSize);
     
+    ball.setVxDir(true);
     ball.setVyDir(true);
     
-    while (!pc.writeable() && !pc.readable()){
+    while (!pc.writeable()){
     
     }
+    
+    Thread thread1(speaker_thread);
+    
+    Thread::wait(5000);
+    
     while (1) 
     {   
         switch (gameState)
         {
         case START:
-        if (pc.writeable()){
-            pc.printf("%c%c%c%c%c\n", 0, 0, 0, 0, 0);
-            wait(.5);
-            gameState = WAIT;
-        }
+            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, gameCenterY, 0, 1);
+            ball.reset(gameCenterX, gameCenterY, 0, sqrt(5.0));
             botPaddle.reset(gameCenterX-(paddleLength/2), gameHighY);
             topPaddle.reset(gameCenterX-(paddleLength/2), gameLowY);
-            ready = false;
-        if (pc.writeable()){
-            pc.printf("%c%c%c%c%c\n", 3, botPaddle.getX(), topPaddle.getX(), ball.getX(), ball.getY());
-            ball.setVx(0);
-            srand(i);
-            //if (rand()%2){
-//                ball.setBaseVy(-1);
-//            }
-//            else{
-//                ball.setBaseVy(1);
-//            }
-            gameState = GAME;
-        }
+            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\n", 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();
-                ball.setVx(topPaddle.returnAngle(fx, size));
-                ball.setVxDir(topPaddle.returnDir(fx, size));
+            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();
+                    double newVx = topPaddle.returnAngle(fx, size);
+                    double newVy = sqrt(5.0 - (newVx * 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();
+                    double newVx = botPaddle.returnAngle(fx, size);
+                    double newVy = sqrt(5.0 - (newVx * newVx));
+                    ball.setVx(newVx);
+                    ball.setVy(newVy);
+                    ball.setVx(botPaddle.returnAngle(fx, size));
+                    ball.setVxDir(botPaddle.returnDir(fx, size));
+                }
+                
+                if (ball.getY() < gameLowY){
+                    botScore++;
+                    gameState = GAME_SETUP;
+                }
+                else if (ball.getY() + size > gameHighY){
+                    topScore++;
+                    gameState = GAME_SETUP;
+                }
+                
+                if (botScore >= 5) {
+                    gameState = WIN;
+                }
+                else if (topScore >= 5) {
+                    gameState = LOSE;   
+                }
+                
+                ball.update();
+                botMove = -joystick.yAxis();
+                if (botMove < -0.25 || botMove > 0.25) {
+                    botPaddle.move(botMove);
+                }
+                //GET OTHER PADDLE SPOT AND UPDATE topPaddle
             }
-            else if (botPaddle.checkHit(ball.getFutureX(), ball.getFutureY(), size)){
-                ball.reverseYDirection();
-                uint8_t fx = ball.getFutureX();
-                ball.setVx(botPaddle.returnAngle(fx, size));
-                ball.setVxDir(botPaddle.returnDir(fx, size));
-            }
-            
-            if (ball.getY() < gameLowY){
-                gameState = WIN;
-            }
-            else if (ball.getY() > gameHighY){
-                gameState = LOSE;
-            }
-            
-            ball.update();
-            botMove = xMove;
-            if (!botMove == .5){
-                botPaddle.move(.5-botMove);
-            }
-            //GET OTHER PADDLE SPOT AND UPDATE topPaddle
-        }
             break;
         case LOSE:
-        if (pc.writeable()){
-            pc.printf("%c%c%c%c%c\n", 5, 0, 0, 0, 0);
-            score = 0;
-            wait(5.0);
-            gameState = START;
-        }
+            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\n", 6, 0, 0, 0, 0);
-            wait(5.0);
-            gameState = START;
-        }
+            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 (ready){
-                pc.printf("%c%c%c%c%c\n", 2, 0, 0, 0, 0);
-                wait(2.0);
-                gameState = GAME_SETUP;
+            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);
+                    Thread::wait(2000);
+                    gameState = GAME_SETUP;
+                }
+                else {
+                    pc.printf("%c%c%c%c%c", 1, 0, 0, 0, 0);
+                }
             }
-            else {
-                pc.printf("%c%c%c%c%c\n", 1, 0, 0, 0, 0);
-            }
-        }
             break;
         }
-        wait_ms(20);
-
+        Thread::wait(20);
     } 
 }
\ No newline at end of file