Categories
algorithm Arduino software

Fun and Games, and a New Library

F+G_Icon

I have for some time wanted to (re)write some of the computer games from my younger days as an exercise in programming and for a bit of fun. I recently decided to do this on a very low-res display made from individual LED matrix modules and in the process created a new library to manage the LED panel display.

Making the Display

One of the characteristics of the ‘retro’ computer games was that screen resolution was exceptionally low.

MAXPanel_1x4_Matrix

The display is made up from five 4×1 MAX7219 LED matrix modules commonly available  online, shown on the left.

To create the display, the modules are stacked so that the DATA IN on the right and snakes back to the right at the end of each row, as shown in the figure and photo below (also described in this previous blog post). Note that the only wiring that actually follows the zig-zag pattern is the DATA OUT to DATA IN. The other signals can all be connected in parallel (in the photo each row is in parallel).

To create a more finished look I then made a frame and stand from plywood, MDF, dowel and acrylic plastic scraps from my woodshop. The final product was a LED matrix display with 40×32 pixel resolution. After running some tests, the power requirement with all LEDs on is in excess of 1A, so the Arduino/USB power supply definitely needs to be replaced with a more capable external supply.

A New Library

I had planned on adding graphics routines to the MD_MAX72xx library to run the 2D matrix, but it quickly became clear that implementing new graphics primitives in this library was the wrong approach. It made more sense to move the few existing graphics functions out of MD_MAX72xx to create the kernel of a new overlay library for a panel of modules.

So the MD_MAXPanel library was born to manage x×y matrix panels. The library enables control of individual LEDs using cartesian coordinates and provides graphics functions for lines, triangles, rectangles, circles and text. The display can also be rotated 90° (for example, from portrait to landscape mode) and a built-in method will automatically adjust the X and Y coordinates.

MAXPanel_Cartesian

In both modes, the (0,0) coordinate for the panel is always in the lowest left hand corner. X and Y coordinates increase to the right and upwards respectively. In cartesian terms, the display is located in the first quadrant (shown with the tick-marked axes in the figure on the right).

Fun and Games

With the screen and the start of the library library sorted I moved on to coding a few games I remember playing in ‘my youth’ (a long time ago now!) –

  • Pong – tennis or ping-pong type game with a bouncing ball. This was the easiest ‘bat and ball’ game to code and provided the template for many of the other games.
  • Bricks – similar to Breakout, where walls of bricks are destroyed by a bouncing ball.
  • Snake – the classic game.
  • Meteor – similar to Asteroids where bullets break up the meteor as it descends towards the shooter. The ‘shooter’ is similar to the Bricks bat although the logic for eliminating bricks was somewhat complicated.
  • Tetris – another classic. This could be a complicated game but my implementation was greatly simplified by a video found on YouTube, referenced in the sketch.
  • TicTacToe – simple kids game. This was a further test of using the MD_TicTacToe library for game logic with a new user interface. See this previous blog post.

To provide the same look and feel for all the games, I made a few early design decisions:

  • The top row of LED matrix modules would display the score, with the remainder of the screen showing the playing field.
  • Re-use code wherever possible. In the end the classes for scoring and sound were identical across all the games, and a function for creating a ‘random’ seed from analog input noise was re-used several times.
  • Sound feedback was going to be the same primitive ‘bips’ and ‘bops’ of those early games. This also made the project simpler as the the standard Tone library and a cheap piezo speaker were sufficient.
  • Standard tact switches would be the user interface. Most games need a subset of Left, Right, Up, and Down (LRUD). I also decided to include Select and Enter (SE) switches. This allowed me to make the very simple ‘game controller’ in the photo at right (click to enlarge) – basically 6 switches all connecting to ground when active.
  • The games would work equally well in portrait or landscape mode just by changing the display mode (ie, no reprogramming). This meant being careful to use adaptable programming constructs rather than hard coding sizes and positions.
  • The small display needed a small font, so I designed a 5×3 font which works well for the numbers displayed but is a bit ‘low res’ for text – readable but very primitive. For me this added to the retro feel for the games.

Even with such a low resolution, the games are fun to play and work well. The video below shows the library being used and features the games. All the applications in the video are part of the examples supplied with the library.

All in all, a fun little project with some good outcomes!

6 replies on “Fun and Games, and a New Library”

Marco
When using the example sketch Parola_Scrolling with version 3.0.1 of the MAX72xx library, a series of 7s appears on the Serial Monitor, even when nothing is connected to the Arduino Uno R3.
The problem does not arise with version 3.0.0 of the MAX72xx library.
Any suggestions to resolve the problem.

Like

Hi Marco,

This is fantastic. I was looking for your input here. I started using your library for a project, combined with a single row of 8 MAXX7219 modules (so 8 x 64 pixels), but recently have become interested in using one of these panels:

https://www.aliexpress.com/item/WERALED-RGB-P4-LED-Displays-Module-SMD-3-in-1-RGB-P4-Indoor-Full-Color-LED/32845761704.html

What I would love to do is break this into ‘zones’ and use MD_Parola (and probably enhance it for colour text etc.) for these. Of course, this would mean most text would be limited to 8 pixels in height based on your pre-defined fonts, but that’s good enough.

Do you have suggestions on the best way to go about this? I was thinking of some how trying to get MD_Parola to work on top of an existing library, similar to your MD_Panel library, that’s designed to pump pixels to these displays: https://github.com/2dom/PxMatrix

Curious on your thoughts on the best way to implement this, maybe I should create a MD_PxMatrixPanel !?

Like

Not sure how these panels work, but essentially one part of the code code needs to be able to initialise the hardware and manage the refresh of the hardware with new data from an internal buffer. The buffer is used to make sure that updates are smooth and occur all at once.

As for high level functions with all these panels/led strips, you essentially need to write one function to turn a pixel on or off given a set of coordinates. That is then used by all the other functions (lines, circles, text, etc) to do their work. I covered some of this in the articles on LED cubes (https://arduinoplusplus.wordpress.com/2015/08/13/device-independent-control-for-led-cubes/ and https://arduinoplusplus.wordpress.com/2018/03/08/revisiting-device-independent-control-for-led-cubes/).

If you look at the MD_MAXPanel library, this is the way that it works. The pixel function then invokes the MD_MAX72xx to manage the pixel on/off. MD_Parola is pretty much the same, except that I provided a few additional functions in MD_MAX72xx to manage transformations (shifts, etc) and fonts. This was done to make the code more efficient – knowing the hardware structure you can, for example, move a column at once instead of a doing it as a sequence of pixels in a for(;;) loop.

If you just rewrite MD_MAX72xx, have the same method names doing the same things with different underlying hardware, then the whole thing should just work.

You may also want to look at the Parola A to Z series of blogs that discuss some of the ways that Parola and MD_MAX72xx work.

Hope this helps and good luck with your project.

Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s