Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE PinDetect SparkfunAnalogJoystick mbed-rtos mbed SDFileSystem
Fork of 4180FinalLab by
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
