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.

Game.cpp

Committer:
john_ghielec
Date:
2014-11-17
Revision:
1:cd8a3926f263
Child:
2:6ab46f2e851a

File content as of revision 1:cd8a3926f263:

#include "Game.h"

const char* Game::LOSE_1 = "You lose.";
const char* Game::LOSE_2 = "Press ship to restart.";
const char* Game::SPLASH = "Press ship to start.";
    
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());
    
    this->initialize();
}

void Game::initialize() {    
    this->initializeBall();
        
    this->paddleX = DisplayN18::WIDTH / 2 - Game::PADDLE_WIDTH / 2;
    this->pwmTicksLeft = 0;
    this->lives = 4;
    
    this->pwm.period_ms(1);
    this->pwm.write(0.00);
    
    this->disp.clear();
}
    
void Game::initializeBall() {
    this->ballX = DisplayN18::WIDTH / 2 - Game::BALL_RADIUS;
    this->ballY = DisplayN18::HEIGHT / 4 - Game::BALL_RADIUS;
    
    this->ballSpeedX = rand() % (Game::MAX_BALL_SPEED * 2);
    this->ballSpeedY = rand() % (Game::MAX_BALL_SPEED * 2);
    
    this->ballSpeedX -= Game::MAX_BALL_SPEED;
    this->ballSpeedY -= Game::MAX_BALL_SPEED;
    
    if (this->ballSpeedX == 0)
        this->ballSpeedX++;
    
    if (this->ballSpeedY == 0)
        this->ballSpeedY--;
}

void Game::tick() {
    this->clearPaddle();
    this->clearBall();
    
    this->updatePaddle();
    this->updateBall();

    this->checkCollision();
    
    this->drawPaddle();        
    this->drawBall();
    
    this->checkPwm();
    this->checkLives();    
}

void Game::drawString(const char* str, int y) {
    this->disp.drawString(DisplayN18::WIDTH / 2 - (DisplayN18::CHAR_WIDTH + DisplayN18::CHAR_SPACING) * strlen(str) / 2, y, str, DisplayN18::WHITE, DisplayN18::BLACK);         
}

void Game::showSplashScreen() {
    this->drawString(Game::SPLASH, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT / 2);  
       
    while (this->circle.read())
        wait_ms(1);
        
    this->disp.clear();
}

void Game::clearPaddle() {
    this->disp.fillRect(this->paddleX, DisplayN18::HEIGHT - Game::PADDLE_HEIGHT, Game::PADDLE_WIDTH, Game::PADDLE_HEIGHT, DisplayN18::BLACK);    
}

void Game::drawPaddle() {
    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())
        this->paddleX += Game::PADDLE_SPEED;
        
    if (this->right.read())
        this->paddleX -= Game::PADDLE_SPEED;
}

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); 
}

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); 
}

void Game::updateBall() {
    this->ballX += this->ballSpeedX;
    this->ballY += this->ballSpeedY;
}

void Game::checkCollision() {    
    if (this->paddleX < 0)
        this->paddleX = 0;
        
    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))
        this->ballSpeedX *= -1;
        
    if (this->ballY - Game::BALL_RADIUS < 0 && this->ballSpeedY < 0)
        this->ballSpeedY *= -1;
        
    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--;
        }
        else if (this->ballX > this->paddleX && this->ballX < this->paddleX + Game::PADDLE_WIDTH) {
            this->ballSpeedY *= -1;
            
            this->pwmTicksLeft = Game::BOUNCE_SOUND_TICKS;                       
        }
    }
}

void Game::checkPwm() {
    if (this->pwmTicksLeft == 0) {
        this->pwm.write(0.0);
    }
    else {
        this->pwmTicksLeft--;
        this->pwm.write(0.5); 
    }
}

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);  
        
        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);   
    }
}