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.
Fork of RETRO_Pong_Mod by
Revision 4:9ad3bc45b6ce, committed 2015-01-15
- Comitter:
 - maxint
 - Date:
 - Thu Jan 15 14:34:59 2015 +0000
 - Parent:
 - 3:2f09c90a732d
 - Commit message:
 - mod150115; - Added paddle control using tilting of the console; - Reduced flickering; - Finished mute function
 
Changed in this revision
| Game.cpp | Show annotated file Show diff for this revision Revisions of this file | 
| Game.h | Show annotated file Show diff for this revision Revisions of this file | 
--- a/Game.cpp	Thu Jan 15 12:48:21 2015 +0000
+++ b/Game.cpp	Thu Jan 15 14:34:59 2015 +0000
@@ -1,11 +1,20 @@
 // Updated version of the official firmware for the Outrageous Circuits RETRO
-// Modified by G. Andrew Duthie (devhammer)
+//
+// mod150106 - Modified by G. Andrew Duthie (devhammer)
 // Changes:
 // - Added sounds for all ball bounces
 // - Changed ball from square to circle
 // - Adjusted collision detection to add ball speed every 10 paddle hits
 // - Added scoring
 // - Added mute function (not fully implemented...needs to be set up on a button).
+//
+// mod150115 - Modified by Maxint
+// Changes:
+// - Upped the I2C frequency to make the Accelerometer useable in actual gameplay
+// - Added paddle control using tilting of the console
+// - Changed left-right button control to make it a bit more logical
+// - tied mute function to the circle button and added el cheapo debouncing
+// - reduced flickering by only redrawing paddle and ball when changed position
 
 #include "Game.h"
 
@@ -21,9 +30,11 @@
     
     this->lastUp = false;
     this->lastDown = false;
-    this->mode = true;
+    this->mode = true;      // true=game, false=accelerometer
     
-    this->i2c.frequency(400);
+    //this->i2c.frequency(400);       // Really? Is this a joke? 400 Hz is much too slow. Reading the XYZ now takes 210 ms
+    this->i2c.frequency(400000);      // fast I2C is 400 KHz, not 400 Hz. Default frequency is 100 KHz, but the faster, the less delay...
+
     this->writeRegister(0x2A, 0x01); 
     
     this->colors[0] = DisplayN18::RED;
@@ -104,6 +115,7 @@
     this->initializeBall();
         
     this->paddleX = DisplayN18::WIDTH / 2 - Game::PADDLE_WIDTH / 2;
+    this->paddleXprev=this->paddleX;
     this->pwmTicksLeft = 0;
     this->lives = 4;
     this->score = 0;
@@ -118,6 +130,8 @@
 void Game::initializeBall() {
     this->ballX = DisplayN18::WIDTH / 2 - Game::BALL_RADIUS;
     this->ballY = DisplayN18::HEIGHT / 4 - Game::BALL_RADIUS;
+    this->ballXprev=this->ballX;
+    this->ballYprev=this->ballY;
     
     this->ballSpeedX = Game::BALL_STARTING_SPEED;
     this->ballSpeedY = Game::BALL_STARTING_SPEED;
@@ -130,16 +144,16 @@
     this->checkButtons();
     
     if (this->mode) {
-        this->clearPaddle();
-        this->clearBall();
+        //this->clearPaddle();
+        //this->clearBall();
         
         this->updatePaddle();
         this->updateBall();
     
         this->checkCollision();
         
-        this->drawPaddle();        
-        this->drawBall();
+        this->redrawPaddle();        
+        this->redrawBall();
         
         this->checkPwm();
         this->checkLives(); 
@@ -156,12 +170,25 @@
         this->drawPoint(1, y);
         this->drawPoint(2, z);
         this->graphX++;
+
+        wait_ms(100);   // added delay after upping the I2C frequency to a usable value
     } 
 }
 
+
+int Game::checkTilt()
+{    // check the orientation of the console to allow tilt-control
+    double x, y, z;
+    
+    this->getXYZ(x, y, z);
+
+    if(x<-0.07) return(-1);     // Using 0.1 requires too much an angle for nice gameplay. 0.07 is more subtle.
+    else if(x>0.07) return(1);
+    else return(0);
+}
+
 void Game::checkButtons() {
     if (!this->square.read()) {
-        //this->muted = !this->muted;
         this->mode = !this->mode;
         
         this->disp.clear();
@@ -172,11 +199,14 @@
             this->drawAxes();
         }
         
-        //this->led1.write(this->muted);
-        //this->led2.write(!this->muted);
-        this->led1.write(this->mode);
-        this->led2.write(!this->mode);
-    }  
+        this->led1.write(!this->mode);
+    }
+    else if(!this->circle.read()) { 
+        // use ship-button to mute
+        this->muted = !this->muted;
+        this->led2.write(this->muted);
+        wait_ms(250);   // el-cheapo deboounce
+    }
     
     bool xDir = this->ballSpeedX > 0;
     bool yDir = this->ballSpeedY > 0;
@@ -219,6 +249,7 @@
        
     while (this->circle.read())
         wait_ms(1);
+    wait_ms(250);   // el-cheapo deboounce
         
     this->disp.clear();
 }
@@ -231,12 +262,30 @@
     this->disp.fillRect(this->paddleX, DisplayN18::HEIGHT - Game::PADDLE_HEIGHT, Game::PADDLE_WIDTH, Game::PADDLE_HEIGHT, DisplayN18::BLUE);    
 }
 
+void Game::redrawPaddle()
+{   // draw the paddle, but only clear when changed to reduce flickering
+    if(this->paddleXprev!=this->paddleX)
+    {
+        this->disp.fillRect(this->paddleXprev, DisplayN18::HEIGHT - Game::PADDLE_HEIGHT, Game::PADDLE_WIDTH, Game::PADDLE_HEIGHT, DisplayN18::BLACK);    
+    }
+    this->disp.fillRect(this->paddleX, DisplayN18::HEIGHT - Game::PADDLE_HEIGHT, Game::PADDLE_WIDTH, Game::PADDLE_HEIGHT, DisplayN18::BLUE);    
+}
+
 void Game::updatePaddle() {
-    if (this->left.read())
+    // see if the paddle position needs changing
+    this->paddleXprev=this->paddleX;
+    if(!this->left.read())  // note: button.read() is LOW (0) when button pressed
+        this->paddleX -= Game::PADDLE_SPEED;
+    else if(!this->right.read())
         this->paddleX += Game::PADDLE_SPEED;
-        
-    if (this->right.read())
-        this->paddleX -= Game::PADDLE_SPEED;
+    else
+    {
+        int nTilt=this->checkTilt();        // don't call too often as this I2C is slow and will delay the game
+        if(nTilt>0)
+            this->paddleX += Game::PADDLE_SPEED;
+        else if(nTilt<0)
+            this->paddleX -= Game::PADDLE_SPEED;
+    }
 }
 
 void Game::clearBall() {   
@@ -246,6 +295,12 @@
     this->disp.setPixel(this->ballX, this->ballY, DisplayN18::BLACK);
 }
 
+void Game::clearBallPrev()
+{   // clear the ball from previous position
+    this->disp.fillCircle(this->ballXprev, this->ballYprev, Game::BALL_RADIUS, DisplayN18::BLACK);
+    this->disp.setPixel(this->ballXprev, this->ballYprev, DisplayN18::BLACK);
+}
+
 void Game::drawBall() {
     //this->disp.fillRect(this->ballX - Game::BALL_RADIUS, ballY - Game::BALL_RADIUS, Game::BALL_RADIUS * 2, Game::BALL_RADIUS * 2, DisplayN18::RED);
     //this->disp.fillCircle(this->ballX - Game::BALL_RADIUS, ballY - Game::BALL_RADIUS, Game::BALL_RADIUS, DisplayN18::RED);
@@ -253,7 +308,20 @@
     this->disp.setPixel(this->ballX, this->ballY, DisplayN18::GREEN);
 }
 
+void Game::redrawBall()
+{   // redraw the ball, but only clear when changed to reduce flickering
+    if(this->ballX!=this->ballXprev || this->ballY!=this->ballYprev)
+    {
+        this->disp.fillCircle(this->ballXprev, this->ballYprev, Game::BALL_RADIUS, DisplayN18::BLACK);
+        this->disp.setPixel(this->ballXprev, this->ballYprev, DisplayN18::BLACK);
+    }
+    this->disp.fillCircle(this->ballX, ballY, Game::BALL_RADIUS, DisplayN18::RED);
+    this->disp.setPixel(this->ballX, this->ballY, DisplayN18::GREEN);
+}
+
 void Game::updateBall() {
+    this->ballXprev=this->ballX;
+    this->ballYprev=this->ballY;
     this->ballX += this->ballSpeedX;
     this->ballY += this->ballSpeedY;
 }
@@ -284,6 +352,7 @@
         
     if (this->ballY + Game::BALL_RADIUS >= DisplayN18::HEIGHT - Game::PADDLE_HEIGHT && this->ballSpeedY > 0) {
         if (this->ballY + Game::BALL_RADIUS >= DisplayN18::HEIGHT) {
+            this->clearBallPrev();
             this->initializeBall();
             
             this->lives--;
--- a/Game.h	Thu Jan 15 12:48:21 2015 +0000
+++ b/Game.h	Thu Jan 15 14:34:59 2015 +0000
@@ -23,10 +23,13 @@
     static const char I2C_ADDR = 0x1C << 1;
     
     int ballX;
+    int ballXprev;
     int ballY;
+    int ballYprev;
     int ballSpeedX;
     int ballSpeedY;
     int paddleX;
+    int paddleXprev;
     int pwmTicksLeft;
     int lives;
     int score;
@@ -67,12 +70,16 @@
     
     void clearPaddle();
     void drawPaddle();
+    void redrawPaddle();
     void updatePaddle();
     
     void clearBall();
+    void clearBallPrev();
     void drawBall();
+    void redrawBall();
     void updateBall();
     
+    int checkTilt();
     void checkButtons();
     void checkCollision();
     void checkPwm();
    