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:
devhammer
Date:
Thu Jan 15 12:48:21 2015 +0000
Parent:
2:6ab46f2e851a
Child:
4:9ad3bc45b6ce
Commit message:
First commit of modified Pong game for RETRO.

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	Fri Nov 21 20:13:10 2014 +0000
+++ b/Game.cpp	Thu Jan 15 12:48:21 2015 +0000
@@ -1,9 +1,20 @@
+// Updated version of the official firmware for the Outrageous Circuits RETRO
+// 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).
+
 #include "Game.h"
 
 const char* Game::LOSE_1 = "You lose.";
 const char* Game::LOSE_2 = "Press ship to restart.";
 const char* Game::SPLASH_1 = "Press ship to start.";
 const char* Game::SPLASH_2 = "Press robot to switch.";
+const char* Game::LIVES = "Lives: ";
+const char* Game::SCORE = "Score: ";
     
 Game::Game() : left(P0_14, PullUp), right(P0_11, PullUp), down(P0_12, PullUp), up(P0_13, PullUp), square(P0_16, PullUp), circle(P0_1, PullUp), led1(P0_9), led2(P0_8), pwm(P0_18), ain(P0_15), i2c(P0_5, P0_4) {
     srand(this->ain.read_u16());
@@ -95,8 +106,10 @@
     this->paddleX = DisplayN18::WIDTH / 2 - Game::PADDLE_WIDTH / 2;
     this->pwmTicksLeft = 0;
     this->lives = 4;
+    this->score = 0;
+    this->muted = false;
     
-    this->pwm.period_ms(1);
+    this->pwm.period(1);
     this->pwm.write(0.00);
     
     this->disp.clear();
@@ -106,8 +119,11 @@
     this->ballX = DisplayN18::WIDTH / 2 - Game::BALL_RADIUS;
     this->ballY = DisplayN18::HEIGHT / 4 - Game::BALL_RADIUS;
     
-    this->ballSpeedX = rand() % 2 ? 1 : -1;
-    this->ballSpeedY = rand() % 2 ? 1 : -1;
+    this->ballSpeedX = Game::BALL_STARTING_SPEED;
+    this->ballSpeedY = Game::BALL_STARTING_SPEED;
+
+    this->ballSpeedX *= (rand() % 2 ? 1 : -1);
+    this->ballSpeedY *= (rand() % 2 ? 1 : -1);
 }
 
 void Game::tick() {  
@@ -145,6 +161,7 @@
 
 void Game::checkButtons() {
     if (!this->square.read()) {
+        //this->muted = !this->muted;
         this->mode = !this->mode;
         
         this->disp.clear();
@@ -155,6 +172,8 @@
             this->drawAxes();
         }
         
+        //this->led1.write(this->muted);
+        //this->led2.write(!this->muted);
         this->led1.write(this->mode);
         this->led2.write(!this->mode);
     }  
@@ -221,11 +240,17 @@
 }
 
 void Game::clearBall() {   
-    this->disp.fillRect(this->ballX - Game::BALL_RADIUS, ballY - Game::BALL_RADIUS, Game::BALL_RADIUS * 2, Game::BALL_RADIUS * 2, DisplayN18::BLACK); 
+    //this->disp.fillRect(this->ballX - Game::BALL_RADIUS, ballY - Game::BALL_RADIUS, Game::BALL_RADIUS * 2, Game::BALL_RADIUS * 2, DisplayN18::BLACK);
+    //this->disp.fillCircle(this->ballX - Game::BALL_RADIUS, this->ballY - Game::BALL_RADIUS, Game::BALL_RADIUS, DisplayN18::BLACK);
+    this->disp.fillCircle(this->ballX, this->ballY, Game::BALL_RADIUS, DisplayN18::BLACK);
+    this->disp.setPixel(this->ballX, this->ballY, 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.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);
+    this->disp.fillCircle(this->ballX, ballY, Game::BALL_RADIUS, DisplayN18::RED);
+    this->disp.setPixel(this->ballX, this->ballY, DisplayN18::GREEN);
 }
 
 void Game::updateBall() {
@@ -240,29 +265,68 @@
     if (this->paddleX + Game::PADDLE_WIDTH > DisplayN18::WIDTH)
         this->paddleX = DisplayN18::WIDTH - Game::PADDLE_WIDTH;
         
-    if ((this->ballX - Game::BALL_RADIUS < 0 && this->ballSpeedX < 0) || (this->ballX + Game::BALL_RADIUS >= DisplayN18::WIDTH && this->ballSpeedX > 0))
+    //if ((this->ballX - Game::BALL_RADIUS < 0 && this->ballSpeedX < 0) || (this->ballX + Game::BALL_RADIUS >= DisplayN18::WIDTH && this->ballSpeedX > 0)) {
+    if ((this->ballX - Game::BALL_RADIUS < 0 && this->ballSpeedX < 0) || (this->ballX + Game::BALL_RADIUS * 2 >= DisplayN18::WIDTH && this->ballSpeedX > 0)) {
         this->ballSpeedX *= -1;
+        if(!this->muted) {
+            this->pwm.period_ms(2);
+            this->pwmTicksLeft = Game::BOUNCE_SOUND_TICKS;
+        }
+    }
         
-    if (this->ballY - Game::BALL_RADIUS < 0 && this->ballSpeedY < 0)
+    if (this->ballY - Game::BALL_RADIUS < (0 + DisplayN18::CHAR_HEIGHT) && this->ballSpeedY < 0){
         this->ballSpeedY *= -1;
+        if(!this->muted) {
+            this->pwm.period_ms(2);
+            this->pwmTicksLeft = Game::BOUNCE_SOUND_TICKS;
+        }
+    }
         
     if (this->ballY + Game::BALL_RADIUS >= DisplayN18::HEIGHT - Game::PADDLE_HEIGHT && this->ballSpeedY > 0) {
         if (this->ballY + Game::BALL_RADIUS >= DisplayN18::HEIGHT) {
             this->initializeBall();
             
             this->lives--;
+
+            if(this->lives > 0) {
+                if(!this->muted) {
+                    this->pwm.period(1.0/220);
+                    this->pwm.write(0.5);
+                    wait_ms(150);
+                    this->pwm.write(0.0);
+                }
+            }
+
         }
         else if (this->ballX > this->paddleX && this->ballX < this->paddleX + Game::PADDLE_WIDTH) {
             this->ballSpeedY *= -1;
             
-            this->pwmTicksLeft = Game::BOUNCE_SOUND_TICKS;                       
+            if(!this->muted){
+                this->pwm.period_ms(1);
+                this->pwmTicksLeft = Game::BOUNCE_SOUND_TICKS;
+            }
+            this->score = this->score + 10;
+            if(this->score % 100 == 0) {
+                if(this->ballSpeedX < 0){
+                    this->ballSpeedX -= 1;
+                }
+                else {
+                    this->ballSpeedX += 1;
+                }
+                this->ballSpeedY -= 1;
+            }
         }
     }
+    char buf[10];
+    int a = this->score;
+    sprintf(buf, "%d", a);
+    this->disp.drawString(DisplayN18::WIDTH - (DisplayN18::CHAR_WIDTH * 12), 0, Game::SCORE, DisplayN18::WHITE, DisplayN18::BLACK);     
+    this->disp.drawString(DisplayN18::WIDTH - (DisplayN18::CHAR_WIDTH * 4), 0, buf, DisplayN18::WHITE, DisplayN18::BLACK);   
 }
 
 void Game::checkPwm() {
     if (this->pwmTicksLeft == 0) {
-        this->pwm.write(0.0);
+         this->pwm.write(0.0);
     }
     else {
         this->pwmTicksLeft--;
@@ -273,16 +337,34 @@
 void Game::checkLives() {
     if (this->lives == 0) {
         this->disp.clear();
-        
+                
         this->drawString(Game::LOSE_1, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT); 
         this->drawString(Game::LOSE_2, DisplayN18::HEIGHT / 2);  
         
+        if(!this->muted) {
+            this->pwm.period(1.0/220);
+            this->pwm.write(0.5);
+            wait_ms(150);
+            this->pwm.write(0.0);
+    
+            this->pwm.period(1.0/196);
+            this->pwm.write(0.5);
+            wait_ms(150);
+            this->pwm.write(0.0);
+    
+            this->pwm.period(1.0/164.81);
+            this->pwm.write(0.5);
+            wait_ms(150);
+            this->pwm.write(0.0);
+        }
+        
         while (this->circle.read())
             wait_ms(1);
             
         this->initialize();
     }
     else {
-        this->disp.drawCharacter(0, 0, static_cast<char>(this->lives + '0'), DisplayN18::WHITE, DisplayN18::BLACK);   
+        this->disp.drawString(0, 0, Game::LIVES, DisplayN18::WHITE, DisplayN18::BLACK);
+        this->disp.drawCharacter(DisplayN18::CHAR_WIDTH * 8, 0, static_cast<char>(this->lives + '0'), DisplayN18::WHITE, DisplayN18::BLACK);   
     }
 }
\ No newline at end of file
--- a/Game.h	Fri Nov 21 20:13:10 2014 +0000
+++ b/Game.h	Thu Jan 15 12:48:21 2015 +0000
@@ -9,11 +9,14 @@
     static const char* LOSE_2;
     static const char* SPLASH_1;
     static const char* SPLASH_2;
+    static const char* LIVES;
+    static const char* SCORE;
     
     static const int BALL_RADIUS = 3;
+    static const int BALL_STARTING_SPEED = 3;
     static const int PADDLE_WIDTH = 38;
     static const int PADDLE_HEIGHT = 4;
-    static const int PADDLE_SPEED = 4;
+    static const int PADDLE_SPEED = 5;
     static const int BOUNCE_SOUND_TICKS = 2;
     static const int GRAPH_HEIGHT = 40;
     static const int GRAPH_SPACING = 2;
@@ -26,10 +29,12 @@
     int paddleX;
     int pwmTicksLeft;
     int lives;
+    int score;
     int graphX;    
     bool mode;
     bool lastUp;
     bool lastDown;
+    bool muted;
     unsigned short colors[3];
 
     DigitalIn left;