new mods upon mods by devhammer: - Added paddle control using tilting of the console - Finished mute function - Reduced flickering See game.cpp for full info.

Dependencies:   mbed

Fork of RETRO_Pong_Mod by G. Andrew Duthie

This is a mod of the official Pong game released with the RETRO game console.

Files at this revision

API Documentation at this revision

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
diff -r 2f09c90a732d -r 9ad3bc45b6ce Game.cpp
--- 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--;
diff -r 2f09c90a732d -r 9ad3bc45b6ce Game.h
--- 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();