Introduction: From Text to Track: Retro Racing Game on a 16x2 Character LCD With Arduino

Imagine the nostalgia of playing a classic arcade game on a small, pixelated screen. With a 16x2 character display, you can bring that experience to life in a fun and interactive way. Although it provides only text output, you could create up to 8 custom characters and map your logical game space to 16x2 character matrix, as I did in my šŸ‘¾previous LCD game. This time I am going to push hardware limits a little bit further to create more sophisticated animation.

šŸ”— You might also like the video streaming LCD hack I published here.

Supplies

Technically any Arduino board that could interface a 1602 LCD may be used. You could also use bare LCD and a couple of push buttons instead of the shield. However I do not recommend I2C LCDs since they are a bit slower for animation rendering.

Step 1: Animation Techniques

For this project, I utilized a game "engine" from LCD Invaders game. It maps 16x4 game field to 16x2 LCD. But instead of implementing a custom character for every state of the sprite I designed a sort of code-pages approach. Think of each sprite as a deck of cards containing various animation frames of the same character. By rapidly switching these "cards" (custom characters), we can create the illusion of animation on the screen. Through experimentation, I discovered that using lcd.createChar() is significantly faster than lcd.print(). Although we are still limited to displaying only 8 custom characters at a time, we can swiftly replace them to achieve an animated effect across the entire screen.

šŸ’” In the video, you may notice subtle textures resembling moving asphalt. This isn't a glitch; rapidly turning pixels on and off on this type of display creates a grayscale effect. Play with contrast of your display to see it.

Step 2: Schematics

Unless you are strong enough, it is nearly impossible to connect the LCD shield incorrectly. In case you decide to use a bare LCD, I have attached its schematics as a reference.

Step 3: Customizing the Controls

Please download the attached Arduino sketch and open it with Arduino IDE. If your LCD shield is different from mine, you'll probably need to tune ADC button values in the buttonPressed() function. If you decided to use separate push buttons on digital pins instead, your buttonPressed() function would be structured as follows, assuming pins 2 and 3 are used:

byte buttonPressed()
{
 if(!digitalRead(2))
  return btnDOWN;
 if(!digitalRead(3))
  return btnUP;
 return btnNONE;
}

Step 4: Uploading the Code

Connect your board, choose the correct port and press "Upload" button.

Step 5: Game Over?

Looking to level up your gaming experience? Dive into customization by personalizing this game or crafting your very own masterpiece using the same animation technique. Get creative with the spritemap array to give your sprites a unique look. And why stop there? You might also want to port the game to a 20x4 character LCD to have enough space for implementing curved roads.

Share your ideas in the comments below!