Close

What a blast!

A project log for Boom!

Classic artillery game for Arduino

jim-shortzJim Shortz 12/30/2016 at 01:390 Comments

Since I don't believe in publishing half-baked ideas, I did not create the Hackaday.io site until the project was completed. So, this will be a bit of a retrospective.

The Arduino and Touch Shield were gifts from the estate of a recently deceased close friend. It seemed like the perfect platform for a video game project and I wanted to honor Don's memory by carrying on the kind of tinkering he liked to do with these.

Since I was not at all familiar with the touch shield, I decided it best to write a prototype of the game in C using the Arduino software. This let me quickly iterate on the project and find out what kinds of graphics and game flows could be done simply, but still be interesting to play. I tried several different aiming interfaces before deciding on the crosshair. It also let me prove out the fixed point motion algorithms.

As the prototype progressed, I started replacing pieces of the Arduino libraries with my own code to further prove it out. I have included the prototype code in the repo, so you can play that version too!

My first task in the assembler version was to write the motion equations. Those were pretty straightforward and I was happy to see they only used 96 bytes. The next task was far trickier - getting the video routines and touch input working. I used the Arduino libraries as a starting point, but those were written in C, so I had to convert them. That conversion was basically an "all or nothing" operation - it either worked or it didn't. After a few failed attempts, I resorted to using GCC to produce an assembly output and then reformatting that to work in AVRASM. That netted me a working (albeit bloated) driver layer.

Next was the touch screen interface, which went a bit smoother. Last was the game flow, point scoring, etc. By this point it was clear that this wasn't going to begin to fit. Rather than pile up too much "debt", I went through a number of iterations of shrinking things.

Probably the biggest gains were had in the video routines. Since I had a working baseline, I would make very small changes (often a single line at a time) and test as I went. Ultimately I wound up significantly shrinking the send_command, send_data, and send_byte routines which would up being several times faster in the process. The initialization code was also huge. To shrink it, I simply deleted each line of code and re-tested. I deleted most of the lines in that process.

The touch screen interface was my next target at 192 bytes. I was able to hack that down quite a bit by working out an offset, numerator, and denominator that would allow the pressure threshold to be tested using the exact same code as computes the X and Y coordinates. Pretty nifty, heh?

Once I had a working game, I went through several more iterations, which included going back to the prototype. I really wanted to add randomly generated terrain. In order to have a place for the tanks to "rest", I decided to generate the terrain as 5 plateaus and only position tanks on the plateaus. This prevents the "dig into the side of a hill" problem. It was pretty straight forward to generate these, but without interpolation it looked like a Road Runner cartoon. By doing two passes with a 16-element averaging window I was able to produce beautiful curves, but the 16-bit math involved was well over 50 bytes. Turns out that by using a 2-element window I could do it all in 8-bit (terrain is always < 128) and simply ran the algorithm more times.

Anyway, this project was a lot of fun, but it was far more challenging and time consuming than I had originally expected!

Discussions