Retro game that let's the player steer a ball through a hole filled maze. Has multiple levels of increasing difficulty.

Dependencies:   LCD_ST7735 MusicEngine RETRO_BallsAndThings mbed

Ball and Holes

In this game I attempted to create somewhat natural movement of the ball by implementing gravity and friction which combined over time determine the speed of the ball. Playing with the settings (aka. the magic numbers) that are spread out all over game.cpp, gives different effects, such as an icy, rough or liquid-like surface.

It took some time to figure out how to post my very first youtube video. Sorry for the shaky recording. Trying to record the video with my phone while playing the game in one hand was quite challenging, but here it is;

The left and right buttons are used to cheat: restart the current or go to the next level. Up and down control the game-tick. During game-play the robot-button shows the accelerator graph and the ship-button mutes the sound.

BTW. If your ball happens to get stuck, tilting the console in the opposite direction will set it free. For sake of argument: these magnetic wall-ends are in the words of Bob Ross "a happy accident". Since there is no specific code for it, others might call it a bug. As it results in more interesting game-play, I didn't attempt to fix it, but left a comment for those who dare to look at the mess I call code.

Committer:
maxint
Date:
Tue Feb 03 19:02:27 2015 +0000
Revision:
2:d4de5a5866fe
Parent:
1:c1ee4c699517
Added more balls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
maxint 0:87ab172a74b4 1 #include "Accelerometer.h"
maxint 0:87ab172a74b4 2
maxint 1:c1ee4c699517 3 Accelerometer::Accelerometer(int nI2cAddress, LCD_ST7735* pDisp) : i2cAddress(nI2cAddress), i2c(P0_5, P0_4)
maxint 0:87ab172a74b4 4 { // constructor
maxint 0:87ab172a74b4 5 this->i2c.frequency(400000); // fast I2C is 400 KHz, not 400 Hz. Default frequency is 100 KHz
maxint 0:87ab172a74b4 6 this->writeRegister(0x2A, 0x01); // initialize accelerometer (set CTRL_REG1 bit ACTIVE)
maxint 1:c1ee4c699517 7 this->pDisp=pDisp;
maxint 1:c1ee4c699517 8
maxint 1:c1ee4c699517 9 this->colors[0] = Color565::Red;
maxint 1:c1ee4c699517 10 this->colors[1] = Color565::Green;
maxint 1:c1ee4c699517 11 this->colors[2] = Color565::Blue;
maxint 0:87ab172a74b4 12 }
maxint 0:87ab172a74b4 13
maxint 0:87ab172a74b4 14 void Accelerometer::readRegisters(char address, char* buffer, int len) {
maxint 0:87ab172a74b4 15 // int nStart=this->tWait.read_ms();
maxint 0:87ab172a74b4 16 this->i2c.write(i2cAddress, &address, 1, true);
maxint 0:87ab172a74b4 17 this->i2c.read(i2cAddress | 1, buffer, len);
maxint 0:87ab172a74b4 18 // printDouble((double)this->tWait.read_ms()-nStart, 10, 10);
maxint 0:87ab172a74b4 19 }
maxint 0:87ab172a74b4 20
maxint 0:87ab172a74b4 21 int Accelerometer::writeRegister(char address, char value) {
maxint 0:87ab172a74b4 22 char buffer[2] = { address, value };
maxint 0:87ab172a74b4 23
maxint 0:87ab172a74b4 24 return this->i2c.write(i2cAddress, buffer, 2);
maxint 0:87ab172a74b4 25 }
maxint 0:87ab172a74b4 26
maxint 0:87ab172a74b4 27 double Accelerometer::convert(char* buffer) {
maxint 0:87ab172a74b4 28 double val = ((buffer[0] << 2) | (buffer[1] >> 6));
maxint 0:87ab172a74b4 29
maxint 0:87ab172a74b4 30 if (val > 511.0)
maxint 0:87ab172a74b4 31 val -= 1024.0;
maxint 0:87ab172a74b4 32
maxint 0:87ab172a74b4 33 return val / 512.0;
maxint 0:87ab172a74b4 34 }
maxint 0:87ab172a74b4 35
maxint 0:87ab172a74b4 36 void Accelerometer::getXYZ(double& x, double& y, double& z) {
maxint 0:87ab172a74b4 37 char buffer[6];
maxint 0:87ab172a74b4 38
maxint 0:87ab172a74b4 39 this->readRegisters(0x01, buffer, 6);
maxint 0:87ab172a74b4 40
maxint 0:87ab172a74b4 41 x = this->convert(buffer);
maxint 0:87ab172a74b4 42 y = this->convert(buffer + 2);
maxint 0:87ab172a74b4 43 z = this->convert(buffer + 4);
maxint 1:c1ee4c699517 44 }
maxint 1:c1ee4c699517 45
maxint 1:c1ee4c699517 46 //
maxint 1:c1ee4c699517 47 // Accellerator graph for debug purposes
maxint 1:c1ee4c699517 48 //
maxint 1:c1ee4c699517 49
maxint 1:c1ee4c699517 50 void Accelerometer::drawAxes()
maxint 1:c1ee4c699517 51 {
maxint 1:c1ee4c699517 52 for (int i = 0; i < 3; i++) {
maxint 1:c1ee4c699517 53 this->pDisp->fillRect(0, i * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING), this->pDisp->getWidth(), i * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING) + Accelerometer::GRAPH_HEIGHT, Color565::fromRGB(i==0?0x22:0, i==1?0x22:0, i==2?0x22:0));
maxint 1:c1ee4c699517 54 this->pDisp->drawLine(0, i * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING), 0, i * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING) + Accelerometer::GRAPH_HEIGHT, Color565::White);
maxint 1:c1ee4c699517 55 this->pDisp->drawLine(0, i * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING) + Accelerometer::GRAPH_HEIGHT / 2, this->pDisp->getWidth(), i * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING) + Accelerometer::GRAPH_HEIGHT / 2, Color565::White);
maxint 1:c1ee4c699517 56 }
maxint 1:c1ee4c699517 57 }
maxint 1:c1ee4c699517 58
maxint 1:c1ee4c699517 59 void Accelerometer::drawPoint(int axis, double value)
maxint 1:c1ee4c699517 60 {
maxint 1:c1ee4c699517 61 if (value < -1.0)
maxint 1:c1ee4c699517 62 value = -1.0;
maxint 1:c1ee4c699517 63
maxint 1:c1ee4c699517 64 if (value > 1.0)
maxint 1:c1ee4c699517 65 value = 1.0;
maxint 1:c1ee4c699517 66
maxint 1:c1ee4c699517 67 value += 1.0;
maxint 1:c1ee4c699517 68 value /= 2.0;
maxint 1:c1ee4c699517 69 value = 1.0 - value;
maxint 1:c1ee4c699517 70 value *= Accelerometer::GRAPH_HEIGHT;
maxint 1:c1ee4c699517 71
maxint 1:c1ee4c699517 72 this->pDisp->setPixel(this->graphX, axis * (Accelerometer::GRAPH_HEIGHT + Accelerometer::GRAPH_SPACING) + (int)value, this->colors[axis]);
maxint 1:c1ee4c699517 73 }
maxint 1:c1ee4c699517 74
maxint 1:c1ee4c699517 75 void Accelerometer::resetGraph()
maxint 1:c1ee4c699517 76 {
maxint 1:c1ee4c699517 77 this->graphX = 0;
maxint 1:c1ee4c699517 78 this->pDisp->clearScreen();
maxint 1:c1ee4c699517 79 //this->pDisp->fillRect(0, 0, this->pDisp->getWidth(), this->pDisp->getHeight(), Color565::fromRGB(0x11, 0x33, 0x22));
maxint 1:c1ee4c699517 80 this->drawAxes();
maxint 1:c1ee4c699517 81 }
maxint 1:c1ee4c699517 82
maxint 1:c1ee4c699517 83 void Accelerometer::checkGraphReset()
maxint 1:c1ee4c699517 84 {
maxint 1:c1ee4c699517 85 if (this->graphX > this->pDisp->getWidth())
maxint 1:c1ee4c699517 86 {
maxint 1:c1ee4c699517 87 this->resetGraph();
maxint 1:c1ee4c699517 88 }
maxint 1:c1ee4c699517 89 }
maxint 1:c1ee4c699517 90
maxint 1:c1ee4c699517 91 void Accelerometer::updateGraph()
maxint 1:c1ee4c699517 92 {
maxint 1:c1ee4c699517 93 double x, y, z;
maxint 1:c1ee4c699517 94 this->getXYZ(x, y, z);
maxint 1:c1ee4c699517 95
maxint 1:c1ee4c699517 96 this->checkGraphReset();
maxint 1:c1ee4c699517 97 this->drawPoint(0, x);
maxint 1:c1ee4c699517 98 this->drawPoint(1, y);
maxint 1:c1ee4c699517 99 this->drawPoint(2, z);
maxint 1:c1ee4c699517 100 this->graphX++;
maxint 1:c1ee4c699517 101 }
maxint 1:c1ee4c699517 102