Game entry for the Game Programming Contest sponsored by OutrageousCircuits.com (RETRO Game Console)
Fork of Official_RETRO by
Diff: Game.cpp
- Revision:
- 2:6ab46f2e851a
- Parent:
- 1:cd8a3926f263
- Child:
- 3:7680307a02d7
diff -r cd8a3926f263 -r 6ab46f2e851a Game.cpp --- a/Game.cpp Mon Nov 17 19:51:24 2014 +0000 +++ b/Game.cpp Fri Nov 21 20:13:10 2014 +0000 @@ -2,14 +2,93 @@ const char* Game::LOSE_1 = "You lose."; const char* Game::LOSE_2 = "Press ship to restart."; -const char* Game::SPLASH = "Press ship to start."; +const char* Game::SPLASH_1 = "Press ship to start."; +const char* Game::SPLASH_2 = "Press robot to switch."; 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->lastUp = false; + this->lastDown = false; + this->mode = true; + + this->i2c.frequency(400); + this->writeRegister(0x2A, 0x01); + + this->colors[0] = DisplayN18::RED; + this->colors[1] = DisplayN18::GREEN; + this->colors[2] = DisplayN18::BLUE; + this->initialize(); } +void Game::readRegisters(char address, char* buffer, int len) { + this->i2c.write(Game::I2C_ADDR, &address, 1, true); + this->i2c.read(Game::I2C_ADDR | 1, buffer, len); +} + +int Game::writeRegister(char address, char value) { + char buffer[2] = { address, value }; + + return this->i2c.write(Game::I2C_ADDR, buffer, 2); +} + +double Game::convert(char* buffer) { + double val = ((buffer[0] << 2) | (buffer[1] >> 6)); + + if (val > 511.0) + val -= 1024.0; + + return val / 512.0; +} + +void Game::getXYZ(double& x, double& y, double& z) { + char buffer[6]; + + this->readRegisters(0x01, buffer, 6); + + x = this->convert(buffer); + y = this->convert(buffer + 2); + z = this->convert(buffer + 4); +} + +void Game::printDouble(double value, int x, int y) { + char buffer[10]; + int len = sprintf(buffer, "%.1f", value); + + this->disp.drawString(x, y, buffer, DisplayN18::WHITE, DisplayN18::BLACK); +} + +void Game::drawAxes() { + for (int i = 0; i < 3; i++) { + this->disp.drawLine(0, i * (Game::GRAPH_HEIGHT + Game::GRAPH_SPACING), 0, i * (Game::GRAPH_HEIGHT + Game::GRAPH_SPACING) + Game::GRAPH_HEIGHT, DisplayN18::WHITE); + this->disp.drawLine(0, i * (Game::GRAPH_HEIGHT + Game::GRAPH_SPACING) + Game::GRAPH_HEIGHT / 2, DisplayN18::WIDTH, i * (Game::GRAPH_HEIGHT + Game::GRAPH_SPACING) + Game::GRAPH_HEIGHT / 2, DisplayN18::WHITE); + } +} + +void Game::drawPoint(int axis, double value) { + if (value < -1.0) + value = -1.0; + + if (value > 1.0) + value = 1.0; + + value += 1.0; + value /= 2.0; + value = 1.0 - value; + value *= Game::GRAPH_HEIGHT; + + this->disp.setPixel(this->graphX, axis * (Game::GRAPH_HEIGHT + Game::GRAPH_SPACING) + (int)value, this->colors[axis]); +} + +void Game::checkGraphReset() { + if (this->graphX > DisplayN18::WIDTH) { + this->graphX = 0; + this->disp.clear(); + this->drawAxes(); + } +} + void Game::initialize() { this->initializeBall(); @@ -27,33 +106,88 @@ 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 = rand() % 2 ? 1 : -1; + this->ballSpeedY = rand() % 2 ? 1 : -1; +} + +void Game::tick() { + this->checkButtons(); - this->ballSpeedX -= Game::MAX_BALL_SPEED; - this->ballSpeedY -= Game::MAX_BALL_SPEED; + if (this->mode) { + this->clearPaddle(); + this->clearBall(); + + this->updatePaddle(); + this->updateBall(); - if (this->ballSpeedX == 0) - this->ballSpeedX++; - - if (this->ballSpeedY == 0) - this->ballSpeedY--; + this->checkCollision(); + + this->drawPaddle(); + this->drawBall(); + + this->checkPwm(); + this->checkLives(); + + wait_ms(25); + } + else { + double x, y, z; + + this->getXYZ(x, y, z); + + this->checkGraphReset(); + this->drawPoint(0, x); + this->drawPoint(1, y); + this->drawPoint(2, z); + this->graphX++; + } } -void Game::tick() { - this->clearPaddle(); - this->clearBall(); +void Game::checkButtons() { + if (!this->square.read()) { + this->mode = !this->mode; + + this->disp.clear(); + + if (!this->mode) { + this->graphX = 0; + + this->drawAxes(); + } + + this->led1.write(this->mode); + this->led2.write(!this->mode); + } + + bool xDir = this->ballSpeedX > 0; + bool yDir = this->ballSpeedY > 0; + bool isUp = !this->up.read(); + bool isDown = !this->down.read(); - this->updatePaddle(); - this->updateBall(); - - this->checkCollision(); + if (isUp && isDown) goto end; + if (!isUp && !isDown) goto end; + + if (isUp && this->lastUp) goto end; + if (isDown && this->lastDown) goto end; + + if (!xDir) this->ballSpeedX *= -1; + if (!yDir) this->ballSpeedY *= -1; - this->drawPaddle(); - this->drawBall(); + if (isUp) { + if (++this->ballSpeedX > 5) this->ballSpeedX = 5; + if (++this->ballSpeedY > 5) this->ballSpeedY = 5; + } + else if (isDown) { + if (--this->ballSpeedX == 0) this->ballSpeedX = 1; + if (--this->ballSpeedY == 0) this->ballSpeedY = 1; + } - this->checkPwm(); - this->checkLives(); + if (!xDir) this->ballSpeedX *= -1; + if (!yDir) this->ballSpeedY *= -1; + +end: + this->lastUp = isUp; + this->lastDown = isDown; } void Game::drawString(const char* str, int y) { @@ -61,7 +195,8 @@ } void Game::showSplashScreen() { - this->drawString(Game::SPLASH, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT / 2); + this->drawString(Game::SPLASH_1, DisplayN18::HEIGHT / 2 - DisplayN18::CHAR_HEIGHT / 2); + this->drawString(Game::SPLASH_2, DisplayN18::HEIGHT / 2 + DisplayN18::CHAR_HEIGHT / 2); while (this->circle.read()) wait_ms(1);