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.

Committer:
john_ghielec
Date:
Mon Nov 17 19:51:24 2014 +0000
Revision:
1:cd8a3926f263
Child:
2:6ab46f2e851a
Split game logic out into a game file.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
john_ghielec 1:cd8a3926f263 1 #include "Game.h"
john_ghielec 1:cd8a3926f263 2
john_ghielec 1:cd8a3926f263 3 const char* Game::LOSE_1 = "You lose.";
john_ghielec 1:cd8a3926f263 4 const char* Game::LOSE_2 = "Press ship to restart.";
john_ghielec 1:cd8a3926f263 5 const char* Game::SPLASH = "Press ship to start.";
john_ghielec 1:cd8a3926f263 6
john_ghielec 1:cd8a3926f263 7 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) {
john_ghielec 1:cd8a3926f263 8 srand(this->ain.read_u16());
john_ghielec 1:cd8a3926f263 9
john_ghielec 1:cd8a3926f263 10 this->initialize();
john_ghielec 1:cd8a3926f263 11 }
john_ghielec 1:cd8a3926f263 12
john_ghielec 1:cd8a3926f263 13 void Game::initialize() {
john_ghielec 1:cd8a3926f263 14 this->initializeBall();
john_ghielec 1:cd8a3926f263 15
john_ghielec 1:cd8a3926f263 16 this->paddleX = DisplayN18::WIDTH / 2 - Game::PADDLE_WIDTH / 2;
john_ghielec 1:cd8a3926f263 17 this->pwmTicksLeft = 0;
john_ghielec 1:cd8a3926f263 18 this->lives = 4;
john_ghielec 1:cd8a3926f263 19
john_ghielec 1:cd8a3926f263 20 this->pwm.period_ms(1);
john_ghielec 1:cd8a3926f263 21 this->pwm.write(0.00);
john_ghielec 1:cd8a3926f263 22
john_ghielec 1:cd8a3926f263 23 this->disp.clear();
john_ghielec 1:cd8a3926f263 24 }
john_ghielec 1:cd8a3926f263 25
john_ghielec 1:cd8a3926f263 26 void Game::initializeBall() {
john_ghielec 1:cd8a3926f263 27 this->ballX = DisplayN18::WIDTH / 2 - Game::BALL_RADIUS;
john_ghielec 1:cd8a3926f263 28 this->ballY = DisplayN18::HEIGHT / 4 - Game::BALL_RADIUS;
john_ghielec 1:cd8a3926f263 29
john_ghielec 1:cd8a3926f263 30 this->ballSpeedX = rand() % (Game::MAX_BALL_SPEED * 2);
john_ghielec 1:cd8a3926f263 31 this->ballSpeedY = rand() % (Game::MAX_BALL_SPEED * 2);
john_ghielec 1:cd8a3926f263 32
john_ghielec 1:cd8a3926f263 33 this->ballSpeedX -= Game::MAX_BALL_SPEED;
john_ghielec 1:cd8a3926f263 34 this->ballSpeedY -= Game::MAX_BALL_SPEED;
john_ghielec 1:cd8a3926f263 35
john_ghielec 1:cd8a3926f263 36 if (this->ballSpeedX == 0)
john_ghielec 1:cd8a3926f263 37 this->ballSpeedX++;
john_ghielec 1:cd8a3926f263 38
john_ghielec 1:cd8a3926f263 39 if (this->ballSpeedY == 0)
john_ghielec 1:cd8a3926f263 40 this->ballSpeedY--;
john_ghielec 1:cd8a3926f263 41 }
john_ghielec 1:cd8a3926f263 42
john_ghielec 1:cd8a3926f263 43 void Game::tick() {
john_ghielec 1:cd8a3926f263 44 this->clearPaddle();
john_ghielec 1:cd8a3926f263 45 this->clearBall();
john_ghielec 1:cd8a3926f263 46
john_ghielec 1:cd8a3926f263 47 this->updatePaddle();
john_ghielec 1:cd8a3926f263 48 this->updateBall();
john_ghielec 1:cd8a3926f263 49
john_ghielec 1:cd8a3926f263 50 this->checkCollision();
john_ghielec 1:cd8a3926f263 51
john_ghielec 1:cd8a3926f263 52 this->drawPaddle();
john_ghielec 1:cd8a3926f263 53 this->drawBall();
john_ghielec 1:cd8a3926f263 54
john_ghielec 1:cd8a3926f263 55 this->checkPwm();
john_ghielec 1:cd8a3926f263 56 this->checkLives();
john_ghielec 1:cd8a3926f263 57 }
john_ghielec 1:cd8a3926f263 58
john_ghielec 1:cd8a3926f263 59 void Game::drawString(const char* str, int y) {
john_ghielec 1:cd8a3926f263 60 this->disp.drawString(DisplayN18::WIDTH / 2 - (DisplayN18::CHAR_WIDTH + DisplayN18::CHAR_SPACING) * strlen(str) / 2, y, str, DisplayN18::WHITE, DisplayN18::BLACK);
john_ghielec 1:cd8a3926f263 61 }
john_ghielec 1:cd8a3926f263 62
john_ghielec 1:cd8a3926f263 63 void Game::showSplashScreen() {
john_ghielec 1:cd8a3926f263 64 this->drawString(Game::SPLASH, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT / 2);
john_ghielec 1:cd8a3926f263 65
john_ghielec 1:cd8a3926f263 66 while (this->circle.read())
john_ghielec 1:cd8a3926f263 67 wait_ms(1);
john_ghielec 1:cd8a3926f263 68
john_ghielec 1:cd8a3926f263 69 this->disp.clear();
john_ghielec 1:cd8a3926f263 70 }
john_ghielec 1:cd8a3926f263 71
john_ghielec 1:cd8a3926f263 72 void Game::clearPaddle() {
john_ghielec 1:cd8a3926f263 73 this->disp.fillRect(this->paddleX, DisplayN18::HEIGHT - Game::PADDLE_HEIGHT, Game::PADDLE_WIDTH, Game::PADDLE_HEIGHT, DisplayN18::BLACK);
john_ghielec 1:cd8a3926f263 74 }
john_ghielec 1:cd8a3926f263 75
john_ghielec 1:cd8a3926f263 76 void Game::drawPaddle() {
john_ghielec 1:cd8a3926f263 77 this->disp.fillRect(this->paddleX, DisplayN18::HEIGHT - Game::PADDLE_HEIGHT, Game::PADDLE_WIDTH, Game::PADDLE_HEIGHT, DisplayN18::BLUE);
john_ghielec 1:cd8a3926f263 78 }
john_ghielec 1:cd8a3926f263 79
john_ghielec 1:cd8a3926f263 80 void Game::updatePaddle() {
john_ghielec 1:cd8a3926f263 81 if (this->left.read())
john_ghielec 1:cd8a3926f263 82 this->paddleX += Game::PADDLE_SPEED;
john_ghielec 1:cd8a3926f263 83
john_ghielec 1:cd8a3926f263 84 if (this->right.read())
john_ghielec 1:cd8a3926f263 85 this->paddleX -= Game::PADDLE_SPEED;
john_ghielec 1:cd8a3926f263 86 }
john_ghielec 1:cd8a3926f263 87
john_ghielec 1:cd8a3926f263 88 void Game::clearBall() {
john_ghielec 1:cd8a3926f263 89 this->disp.fillRect(this->ballX - Game::BALL_RADIUS, ballY - Game::BALL_RADIUS, Game::BALL_RADIUS * 2, Game::BALL_RADIUS * 2, DisplayN18::BLACK);
john_ghielec 1:cd8a3926f263 90 }
john_ghielec 1:cd8a3926f263 91
john_ghielec 1:cd8a3926f263 92 void Game::drawBall() {
john_ghielec 1:cd8a3926f263 93 this->disp.fillRect(this->ballX - Game::BALL_RADIUS, ballY - Game::BALL_RADIUS, Game::BALL_RADIUS * 2, Game::BALL_RADIUS * 2, DisplayN18::RED);
john_ghielec 1:cd8a3926f263 94 }
john_ghielec 1:cd8a3926f263 95
john_ghielec 1:cd8a3926f263 96 void Game::updateBall() {
john_ghielec 1:cd8a3926f263 97 this->ballX += this->ballSpeedX;
john_ghielec 1:cd8a3926f263 98 this->ballY += this->ballSpeedY;
john_ghielec 1:cd8a3926f263 99 }
john_ghielec 1:cd8a3926f263 100
john_ghielec 1:cd8a3926f263 101 void Game::checkCollision() {
john_ghielec 1:cd8a3926f263 102 if (this->paddleX < 0)
john_ghielec 1:cd8a3926f263 103 this->paddleX = 0;
john_ghielec 1:cd8a3926f263 104
john_ghielec 1:cd8a3926f263 105 if (this->paddleX + Game::PADDLE_WIDTH > DisplayN18::WIDTH)
john_ghielec 1:cd8a3926f263 106 this->paddleX = DisplayN18::WIDTH - Game::PADDLE_WIDTH;
john_ghielec 1:cd8a3926f263 107
john_ghielec 1:cd8a3926f263 108 if ((this->ballX - Game::BALL_RADIUS < 0 && this->ballSpeedX < 0) || (this->ballX + Game::BALL_RADIUS >= DisplayN18::WIDTH && this->ballSpeedX > 0))
john_ghielec 1:cd8a3926f263 109 this->ballSpeedX *= -1;
john_ghielec 1:cd8a3926f263 110
john_ghielec 1:cd8a3926f263 111 if (this->ballY - Game::BALL_RADIUS < 0 && this->ballSpeedY < 0)
john_ghielec 1:cd8a3926f263 112 this->ballSpeedY *= -1;
john_ghielec 1:cd8a3926f263 113
john_ghielec 1:cd8a3926f263 114 if (this->ballY + Game::BALL_RADIUS >= DisplayN18::HEIGHT - Game::PADDLE_HEIGHT && this->ballSpeedY > 0) {
john_ghielec 1:cd8a3926f263 115 if (this->ballY + Game::BALL_RADIUS >= DisplayN18::HEIGHT) {
john_ghielec 1:cd8a3926f263 116 this->initializeBall();
john_ghielec 1:cd8a3926f263 117
john_ghielec 1:cd8a3926f263 118 this->lives--;
john_ghielec 1:cd8a3926f263 119 }
john_ghielec 1:cd8a3926f263 120 else if (this->ballX > this->paddleX && this->ballX < this->paddleX + Game::PADDLE_WIDTH) {
john_ghielec 1:cd8a3926f263 121 this->ballSpeedY *= -1;
john_ghielec 1:cd8a3926f263 122
john_ghielec 1:cd8a3926f263 123 this->pwmTicksLeft = Game::BOUNCE_SOUND_TICKS;
john_ghielec 1:cd8a3926f263 124 }
john_ghielec 1:cd8a3926f263 125 }
john_ghielec 1:cd8a3926f263 126 }
john_ghielec 1:cd8a3926f263 127
john_ghielec 1:cd8a3926f263 128 void Game::checkPwm() {
john_ghielec 1:cd8a3926f263 129 if (this->pwmTicksLeft == 0) {
john_ghielec 1:cd8a3926f263 130 this->pwm.write(0.0);
john_ghielec 1:cd8a3926f263 131 }
john_ghielec 1:cd8a3926f263 132 else {
john_ghielec 1:cd8a3926f263 133 this->pwmTicksLeft--;
john_ghielec 1:cd8a3926f263 134 this->pwm.write(0.5);
john_ghielec 1:cd8a3926f263 135 }
john_ghielec 1:cd8a3926f263 136 }
john_ghielec 1:cd8a3926f263 137
john_ghielec 1:cd8a3926f263 138 void Game::checkLives() {
john_ghielec 1:cd8a3926f263 139 if (this->lives == 0) {
john_ghielec 1:cd8a3926f263 140 this->disp.clear();
john_ghielec 1:cd8a3926f263 141
john_ghielec 1:cd8a3926f263 142 this->drawString(Game::LOSE_1, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT);
john_ghielec 1:cd8a3926f263 143 this->drawString(Game::LOSE_2, DisplayN18::HEIGHT / 2);
john_ghielec 1:cd8a3926f263 144
john_ghielec 1:cd8a3926f263 145 while (this->circle.read())
john_ghielec 1:cd8a3926f263 146 wait_ms(1);
john_ghielec 1:cd8a3926f263 147
john_ghielec 1:cd8a3926f263 148 this->initialize();
john_ghielec 1:cd8a3926f263 149 }
john_ghielec 1:cd8a3926f263 150 else {
john_ghielec 1:cd8a3926f263 151 this->disp.drawCharacter(0, 0, static_cast<char>(this->lives + '0'), DisplayN18::WHITE, DisplayN18::BLACK);
john_ghielec 1:cd8a3926f263 152 }
john_ghielec 1:cd8a3926f263 153 }