
player 1
Dependencies: 4DGL-uLCD-SE PinDetect SparkfunAnalogJoystick mbed-rtos mbed SDFileSystem
Fork of 4180FinalLab by
Wireless 2 Player Pong game
Revision 3:591086e44bf9, committed 2016-04-24
- Comitter:
- rishibhargava1
- Date:
- Sun Apr 24 01:23:28 2016 +0000
- Parent:
- 2:6163865f5ce3
- Child:
- 4:7da18e3c590b
- Commit message:
- Directions of the ball velocities are bools
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ball.cpp Sun Apr 24 01:23:28 2016 +0000 @@ -0,0 +1,76 @@ +#include "ball.h" + +Ball::Ball(uint8_t initx, uint8_t inity, uint8_t size){ + x = initx; + y = inity; + diameter = size; +} + +void Ball::setVx(uint8_t newvx){ + vx = newvx; +} + +void Ball::setVxDir(bool dir){ + vxDir = dir; +} + +void Ball::setBaseVy(uint8_t baseVy){ + vy = baseVy; +} + +void Ball::setVyDir(bool dir){ + vyDir = dir; +} + +uint8_t Ball::getSize(){ + return diameter; +} + +uint8_t Ball::getX(){ + return x; +} + +uint8_t Ball::getY(){ + return y; +} + +uint8_t Ball::getFutureX(){ + if (vxDir) + return x+vx; + else + return x-vx; +} + +uint8_t Ball::getFutureY(){ + if (vyDir) + return y+vy; + else + return y-vy; +} + +void Ball::reverseXDirection(){ + vxDir = !vxDir; +} + +void Ball::reverseYDirection(){ + vyDir = !vyDir; +} + +void Ball::reset(uint8_t newx, uint8_t newy, int newvx, int newvy){ + x = newx; + y = newy; + vx = newvx; + vy = newvy; +} + +void Ball::update(){ + if (vxDir) + x = x+vx; + else + x = x-vx; + + if (vyDir) + y = y+vy; + else + y = y-vy; +} \ No newline at end of file
--- a/ball.h Fri Jun 20 15:22:28 2014 +0000 +++ b/ball.h Sun Apr 24 01:23:28 2016 +0000 @@ -1,43 +1,32 @@ -#include "tempModule.h" #include "uLCD_4DGL.h" class Ball { public: - // Constructors - Ball (); - Ball (float, float, int); - /* For Part 3: - * you need to be able to pass a pin to the - * tempModule object from main, so you should - * add in a PinName argument. - */ - Ball(PinName); - Ball(PinName, float, float, int); - */ + Ball (uint8_t, uint8_t, uint8_t); // Set Functions - void setBaseVx(float); // This sets the lowest velocity of vx (for Thermal pong) or the constant velocity - void setBaseVy(float); // This sets the lowest velocity of vy (for Thermal pong) or the constant velocity - void setVxSign(int); - void setVySign(int); + void setVx(uint8_t); // This sets the velocity + void setVxDir(bool); + void setBaseVy(uint8_t); // This sets the velocity + void setVyDir(bool); // Get Functions - int getFutureX(); // get estimate of where the ball will be in the next update() - int getFutureY(); // get estimate of where the ball will be in the next update() + uint8_t getSize(); + uint8_t getX(); + uint8_t getY(); + uint8_t getFutureX(); // get estimate of where the ball will be in the next update() + uint8_t getFutureY(); // get estimate of where the ball will be in the next update() // Member Functions void reverseXDirection(); // negate the sign for when a ball hits something void reverseYDirection(); // negate the sign for when a ball hits something - void reset(int, int, int, int, uLCD_4DGL *); // takes in a new location and new directions and draws the starting point for the ball - void update(uLCD_4DGL *); // moves the ball on the screen one vx and vy + void reset(uint8_t, uint8_t, int, int); // takes in a new location and new directions and draws the starting point for the ball + void update(); // moves the ball on the screen one vx and vy private: - // Data members are suggestions, feel free to add/remove - TempModule *tempSensor; // Pointer -- it's recommended to use "new" operator to create this - int vxSign; - int vySign; - float fx; - float fy; - int x; - int y; - int radius; - bool lose; + uint8_t vx; + bool vxDir; //false is left (-x), true is right (+x) + uint8_t vy; + bool vyDir; //false is up (-y), true is down (+y) + uint8_t x; + uint8_t y; + uint8_t diameter; };
--- a/main.cpp Fri Jun 20 15:22:28 2014 +0000 +++ b/main.cpp Sun Apr 24 01:23:28 2016 +0000 @@ -1,25 +1,18 @@ #include "mbed.h" #include "PinDetect.h" -#include "uLCD_4DGL.h" #include "Speaker.h" +#include "paddle.h" +#include "ball.h" // Pushbuttons -PinDetect pbUp(p15); -PinDetect pbDown(p16); -// uLCD -uLCD_4DGL uLCD(p28, p27, p29); +AnalogIn xMove(p15); +PinDetect select(p13); //Speaker -Speaker mySpeaker(p21); - -// Global variables needed for the push button interrupts -int cornerX = 118, cornerY = 1; -int oldCornerY = 1; -int paddleMove = 8; -int length = 40; -int width = 3; +//Speaker mySpeaker(p20); +Serial pc(USBTX, USBRX); // State machine definitions -enum gameStateType {START, WAIT, GAME_SETUP, GAME, LOSE}; +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 @@ -28,158 +21,151 @@ * LOSE -- clears the screen, prints you lose, waits, then goes back to start */ -// Global state machine variable (So that the pushbuttons can modify it) +// Global state machine variable (So that the select can modify it) gameStateType gameState = START; +bool ready = false; -// Pushbutton callbacks -// WARNING: Do not call to draw anything to the uLCD in these -// as this will cause the uLCD to crash sometimes. Update positions -// and draw elsewhere (like it's done here). -// Only modify the logic inside the callback functions. -void pbUp_hit_callback (void) +// Pushbutton callbacks for selecting to start game +void select_hit_callback (void) { switch (gameState) { case WAIT: - gameState = GAME_SETUP; - break; - case GAME: - if(cornerY > paddleMove) { - cornerY -= paddleMove; - } - break; - } -} - -void pbDown_hit_callback (void) -{ - switch (gameState) - { - case WAIT: - gameState = GAME_SETUP; - break; - case GAME: - if(cornerY < 127 - paddleMove - length){ - cornerY += paddleMove; - } + ready = true; break; } } int main() { - // This is setting up the pushbuttons - // Don't modify this code. - pbUp.mode(PullUp); - pbDown.mode(PullUp); + // This is setting up the joystick select as a pushbutton + select.mode(PullUp); wait(0.1); - pbUp.attach_deasserted(&pbUp_hit_callback); - pbDown.attach_deasserted(&pbDown_hit_callback); - pbUp.setSampleFrequency(); - pbDown.setSampleFrequency(); - // Don't modify this code. + select.attach_deasserted(&select_hit_callback); + select.setSampleFrequency(); - uLCD.display_control(PORTRAIT); - uLCD.cls(); - uLCD.baudrate(BAUD_3000000); - uLCD.background_color(BLACK); + pc.baud(9600); + + 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; + int i = 0; - // Initialize all your variables outside the while/switch statement - // to avoid compiler warning/errors - int vxSign = 1, vySign = 1; - float fx=50.0,fy=21.0,vx=1.6,vy=1.2; - int x=50, y=21, radius=5; - int score = 0; - int i = 0; - int random; - + Paddle botPaddle(gameCenterX-(paddleLength/2), gameHighY, paddleLength, paddleWidth); + botPaddle.setLimits(gameLowX, gameHighX); + botPaddle.setMaxMove(2); + Paddle topPaddle(gameCenterX-(paddleLength/2), gameLowY, paddleLength, paddleWidth); + topPaddle.setLimits(gameLowX, gameHighX); + topPaddle.setMaxMove(2); + Ball ball(gameCenterX, gameCenterY, ballSize); + + ball.setVyDir(true); + + while (!pc.writeable() && !pc.readable()){ + + } while (1) { switch (gameState) { case START: - uLCD.cls(); - uLCD.locate(0,0); - uLCD.printf("Pong!!!\n\n"); - uLCD.printf("Press Key to Start"); + if (pc.writeable()){ + pc.printf("%c%c%c%c%c\n", 0, 0, 0, 0, 0); + wait(.5); gameState = WAIT; + } break; case GAME_SETUP: - uLCD.cls(); - uLCD.line(0, 0, 127, 0, 0xCFB53B); - uLCD.line(127, 0, 127, 127, 0xCFB53B); - uLCD.line(127, 127, 0, 127, 0xCFB53B); - uLCD.line(0, 127, 0, 0, 0xCFB53B); - vx = 1.6; - vy = 1.2; + ball.reset(gameCenterX, gameCenterY, 0, 1); + 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); - random = (rand() % (118 - 2*radius)) + radius; - fx = random; - random = (rand() % (127 - 2*radius)) + radius; - fy = random; - x=(int)fx; y=(int)fy; - random = rand() % 1; - vxSign=-1; vySign=((float)random - 0.5)*2; - uLCD.filled_rectangle(cornerX, cornerY, cornerX+width, cornerY+length, BLUE); + //if (rand()%2){ +// ball.setBaseVy(-1); +// } +// else{ +// ball.setBaseVy(1); +// } gameState = GAME; + } break; case GAME: - if ((fx+vxSign*vx<=radius+1)) - { - vxSign = -vxSign; + 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(); } - if ((fy+vySign*vy<=radius+1) || (fy+vySign*vy>=126-radius)) - { - vySign = -vySign; + else if (ball.getFutureX()+size>=gameHighX){ + ball.reverseXDirection(); } - if (((fx+vxSign*vx >= cornerX) && (fx+vxSign*vx <= cornerX+3)) && - ((fy+vySign*vy>=cornerY) && (fy+vySign*vy<=cornerY+length))) - { - vySign = -vySign; + + 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 ((fx+vxSign*vx>=126-radius)) - { - vx = 0; - vy = 0; + 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; } - if ((fx+vxSign*vx>=cornerX-radius) && (fy+vySign*vy<=cornerY+length) && (fy+vySign*vy>=cornerY)) - { - vxSign = -vxSign; - score++; - uLCD.locate(1,1); - uLCD.printf("%d", score); + + ball.update(); + botMove = xMove; + if (!botMove == .5){ + botPaddle.move(.5-botMove); } - uLCD.circle(x, y, radius, BLACK); - fx=fx+(vxSign*vx); - fy=fy+(vySign*vy); - x=(int)fx; - y=(int)fy; - uLCD.circle(x, y, radius, WHITE); - // We can assume that these for loops are quick enough that the paddle will move only one interval. - // These movements of the paddle have been optimized. Feel free to draw it out to see how it's been done. - if(oldCornerY > cornerY) { - uLCD.filled_rectangle(cornerX, oldCornerY-paddleMove+1, cornerX+width, oldCornerY, BLUE); - uLCD.filled_rectangle(cornerX, oldCornerY+length-paddleMove+1, cornerX+width, oldCornerY+length, BLACK); - oldCornerY = cornerY; - } - else if(oldCornerY < cornerY) { - uLCD.filled_rectangle(cornerX, oldCornerY, cornerX+width, oldCornerY+paddleMove, BLACK); - uLCD.filled_rectangle(cornerX, oldCornerY+length, cornerX+width, oldCornerY+length+paddleMove, BLUE); - oldCornerY = cornerY; - } + //GET OTHER PADDLE SPOT AND UPDATE topPaddle + } break; case LOSE: - uLCD.cls(); - uLCD.printf("YOU LOSE D:"); + if (pc.writeable()){ + pc.printf("%c%c%c%c%c\n", 5, 0, 0, 0, 0); score = 0; wait(5.0); 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; + } break; case WAIT: - // Used to seed the rand() function so we don't get the same starting position every time. - i++; + 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; + } + else { + pc.printf("%c%c%c%c%c\n", 1, 0, 0, 0, 0); + } + } break; } + wait_ms(20); + } } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paddle.cpp Sun Apr 24 01:23:28 2016 +0000 @@ -0,0 +1,69 @@ +#include "paddle.h" + +Paddle::Paddle(uint8_t initx, uint8_t inity, uint8_t olength, uint8_t owidth){ + x = initx; + y = inity; + length = length; + width = width; + if (y < 100){ + bottom = false; + } + else { + bottom = true; + } +} + +void Paddle::setLimits(uint8_t left, uint8_t right){ + leftLim = left; + rightLim = right; +} + +void Paddle::setMaxMove(uint8_t amt){ + maxMove = amt; +} + +uint8_t Paddle::getX(){ + return x; +} + +void Paddle::setX(uint8_t newx){ + x = newx; +} + +void Paddle::move(float amt){ + if (x + amt*maxMove + length > rightLim) + x = rightLim - length; + else if (x + amt*maxMove < leftLim) + x = leftLim; + else + x = x + amt*maxMove; +} + +bool Paddle::checkHit(uint8_t ballX, uint8_t ballY, uint8_t size){ + if (ballX+size/2 >= x && ballX+size/2 <= x+length){ + if (bottom && (ballY+size >= y && ballY <= y+width)){ + return true; + } + else if (!bottom && (ballY <= y+width && ballY+size >= y)){ + return true; + } + } + return false; +} + +uint8_t Paddle::returnAngle(uint8_t ballX, uint8_t size){ + return abs((ballX+size/2 - (x + length/2))); +} + +bool Paddle::returnDir(uint8_t ballX, uint8_t size){ + if (ballX+size/2 > (x+length/2)){ + return true; + } + else + return false; +} + +void Paddle::reset(uint8_t initx, uint8_t inity){ + x = initx; + y = inity; +} \ No newline at end of file
--- a/paddle.h Fri Jun 20 15:22:28 2014 +0000 +++ b/paddle.h Sun Apr 24 01:23:28 2016 +0000 @@ -4,34 +4,29 @@ { public: // Constructors - Paddle(int, int); - Paddle(int, int, int, int); + Paddle(uint8_t, uint8_t, uint8_t, uint8_t); // Set Functions - void setLength(int); - void setWidth(int); - void setPaddleMove(int); - void setLimits(int, int); // upper and lower limits of the paddle - // Get Function - int getScore(); + void setLimits(uint8_t, uint8_t); // left and right limits of the paddle + void setMaxMove(uint8_t); + // Paddle location functions + uint8_t getX(); + void setX(uint8_t); // Member Functions - void movePaddle(bool); // moves the paddle locations (does not draw!) - bool checkHitX(int, int, int); // Using a position and radius, checks to see if something has hit the paddle in the x direction - bool checkHitY(int, int, int); // Using a position and radius, checks to see if something has hit the paddle in the y direction - void resetScore(); // sets score to 0 - void initDraw(uLCD_4DGL *uLCD); // draw the paddle initially (draws the whole thing) - void redraw(uLCD_4DGL *uLCD); // draws the paddle for a move (does NOT draw the whole thing) - + void move(float); // false means move left, true means move right + bool checkHit(uint8_t, uint8_t, uint8_t); // Using a position and size, checks to see if something has hit the paddle + uint8_t returnAngle(uint8_t, uint8_t); // Using a ball x position, gives a return vx and vxDir + bool returnDir(uint8_t, uint8_t); + void reset(uint8_t, uint8_t); private: // Data members are suggestions, feel free to add/remove - int score; - int x; - int y; - int oldy; - int length; - int width; - int paddleMove; - int topLimit; - int bottomLimit; + uint8_t x; + uint8_t y; + uint8_t length; + uint8_t width; + uint8_t maxMove; + uint8_t leftLim; + uint8_t rightLim; + bool bottom; //0 is top, 1 is bottom };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/soundBuilder.cpp Sun Apr 24 01:23:28 2016 +0000 @@ -0,0 +1,70 @@ +#include "Speaker.h" +#include "soundBuilder.h" + +Note::Note(){ + setFreq(0); + setLength(0); + setVolume(0); +} + +Note::Note(float freq, float dur, float vol){ + setFreq(freq); + setLength(dur); + setVolume(vol); +} + +void Note::setFreq(float nfreq){ + freq = nfreq; +} + +void Note::setLength(float dur){ + length = dur; +} + +void Note::setVolume(float vol){ + volume = vol; +} + +float Note::getFreq(){ + return freq; +} + +float Note::getLength(){ + return length; +} + +float Note::getVolume(){ + return volume; +} + +SoundBuilder::SoundBuilder(float freq[], float dur[], float vol[], int numNotes, Speaker *mainspeaker){ + for (int i = 0; i < numNotes; i++){ + song[i].setFreq(freq[i]); + song[i].setLength(dur[i]); + song[i].setVolume(vol[i]); + } + speaker = &(*mainspeaker); +} + +void SoundBuilder::setNote(float freq, float dur, float vol, int noteNum){ + song[noteNum].setFreq(freq); + song[noteNum].setLength(dur); + song[noteNum].setVolume(vol); +} + +void SoundBuilder::playNotes(int start, int stop){ + for (int i = start; i <= stop; i++) + speaker->PlayNote(song[i].getFreq(), song[i].getLength(), song[i].getVolume()); +} + +void SoundBuilder::playSong(){ + playNotes(0, sizeof(song)/sizeof(*song)-1); +} + +void SoundBuilder::clearSong(){ + for (int i = 0; i < sizeof(song)/sizeof(*song); i++){ + song[i].setFreq(0); + song[i].setLength(0); + song[i].setVolume(0); + } +} \ No newline at end of file
--- a/soundBuilder.h Fri Jun 20 15:22:28 2014 +0000 +++ b/soundBuilder.h Sun Apr 24 01:23:28 2016 +0000 @@ -3,8 +3,17 @@ class Note { public: - // You create your own constructors and - // member functions!! + // Constructor + Note (); + Note (float, float, float); + // setters + void setFreq(float); + void setLength(float); + void setVolume(float); + // getters + float getFreq(); + float getLength(); + float getVolume(); private: float freq; float length; @@ -14,11 +23,16 @@ class SoundBuilder { public: - // Set Sounds - // Set Songs + // Set Song + SoundBuilder (float [], float [], float [], int, Speaker *); + // Set sound, where int is the note number starting from 0 + void setNote(float, float, float, int); // Play Sounds + void playNotes(int, int); // Play Songs + void playSong(); // Clear Songs + void clearSong(); private: Note song[20];
--- a/tempModule.h Fri Jun 20 15:22:28 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -#include "uLCD_4DGL.h" - -/* Recommendation: - * This class doesn't need to be declared outside the Ball class, - * so you can create it inside the Ball class and use it only - * in the Ball class. - * - * If the main function or multiple objects use a piece of hardware - * or a class object (like uLCD or mySpeaker), you should pass a - * pointer into the object rather than creating the object (either - * in the stack or using new). - */ - -class TempModule -{ -public: - // Constructors - TempModule(PinName pin); - TempModule(PinName pin, float vx, float vy); - // Reading temperature values - float read(); - // Set Functions - void setBaseVx(float); // This sets the lowest velocity of vx - void setBaseVy(float); // This sets the lowest velocity of vy - // Get Functions/Member Functions - float getVx(); // Calculates a speed based off of the temp - float getVy(); - float getVx(uLCD_4DGL *); // Same thing as getVx(), except it - // also writes the temp to the screen. - -private: - // Data members are suggestions, feel free to add/remove - AnalogIn _sensor; - float roomTemp; - float holdTemp; - float basevx; - float basevy; - int counter; -}; - -TempModule::TempModule (PinName pin) : _sensor(pin) -{ - // Constructor code goes here - // you can ignore initializing _sensor, we've already done that -} - -TempModule::TempModule (PinName pin, float vx, float vy) : _sensor(pin) -{ - // Constructor code goes here - // you can ignore initializing _sensor, we've already done that -} \ No newline at end of file