Flappy Chip is a small game running on the Arduino Uno
board (or standalone atmega328 microcontroller). The purpose of the game is to make the chip pass by as many tubes as you can without hitting them, by pressing the button which makes the chip climb (otherwise it falls). The score represents the number of tube pairs that have been avoided.
The graphic LCD display that I used comes from an old Nokia 3310 cellphone. It is connected to the board using 5 resistive voltage deviders (one for each pin) which act as logic level converters. They are needed because the LCD driver works on 3.3 V whereas the microcontroller works on 5 V. The pins used for the display are digital pins 3 to 7 which have the following functions :
- pin 3 – LCD reset (RST)
- pin 4 – LCD chip select (CS)
- pin 5 – Data/Command select (D/C)
- pin 6 – Serial data out (DIN)
- pin 7 – Serial clock out (SCLK)
The button is connected to pin 2, which is pulled up internally. When the button is pressed, it pulls the pin to the ground, which triggers an interrupt that changes the position of the chip.
Each graphic element was drawn in Paint, saved as a monochrome bitmap and converted to hex values using Image2Code. The bitmaps are stored in the Flash memory of the microcontroller. In order to put elements in front of the background, I had to make solid black bitmaps that are dislpayed negatively so that they clear the pixels of the background where the elements need to be displayed.(otherwise the front elements and the background mix) The whole graphic section is based on the Adafruit PCD8544 and GFX libraries, which makes it easy to use the Nokia display.
After displaying the startup image, the MCU waits for the user to press the button which starts the actual game. Then, the ISR that modifies the chip position is attached and the gameloop begins and runs as long as the chip ,,is alive”. Each time the gameloop is executed, the display is cleared, then the backround is displayed, followed by the chip. The maximum number of the tubes is 8 (4 pairs), since 4 sets of variables have been declared for this purpose. The game starts with one pair. The pairs are cycled in and out, gradually decreasing distance between the tubes and gradually adding more tubes until all four pairs are needed. A series of if statements checks whether one of the tubes have gone offscreen and makes the corresponding variable false. Then if the rightmost tube is at the desired distance from the right margin of the screen, a new pair of tubes is reintroduced by reinitializing their corresponding variables. The vertical position is set at random. Another series of if statements moves the onscreen tubes to the left by one pixel. Afterwards, the tubes and the score are displayed. Then, the coordinates of the chip and the coordinates of the tubes are compared and in case of collision the alive variable is set to false and procedure dead is called which makes the chip fall. The chip is not allowed to hit the margins of the screen so if that happens it is considered ,,dead” as well. Finally, the score is incremented as each pair of tubes is avoided, the chip’s vertical position is incremented (so that it falls unless you press the button) and the delay keeps the game from running at lightning speed (or not really, with only 16 MHz clock speed). After the gameloop, the button interrupt is detached and the score is compared to the highscore (if there is one in the EEPROM). If there is no highscore, or your current score is higher than the highscore, a new higscore is written in the EEPROM so that it will not be lost when the MCU loses power. And just in case you become addicted to this game, you don’t have to worry about EEPROM wear out because a memory wear leveling algorithm writes the highscore at a different adress each time.