I have build an Arcade Retro Clock, powered by Raspberry Pi A+ and a Unicorn HAT. 64 pixels of glorious color.
That’s incredible. How do you manage the animations/get them so fluid? Any tricks, or just artistry and a whole bunch of frames?
I use several methods. I first started toying with “sprites” which were just a single dimension array 0-63, each element represented a pixel from top left to bottom right. I was just learning Python and did not know the syntax to make a multi dimensional array / list, so I came up with a bizarre chunk of code that would take that array and break it up into rows (Divmod is my friend!). Based on that, I started tinkering with custom width sprites so I could draw the alphabet and numbers. Here is the number 8:
Each 1 represents “this pixel is lit”, the 0 means “unlit”. The color is set for all pixels at the same time. This was primitive, but allowed me to visualize the character as I was hand drawing them.
My coloring strategy evolved into having 30 pre-defined colors, represented by nunbers 0-29 (shades of white, red, blue, green, yellow, purple) which allowed my son (he is 8) to draw the chicken:
ChickenRunning = ColorAnimatedSprite(h=0, v=0, name=“Chicken”, width=8, height=8, frames=4, currentframe=0,framerate=1,grid=)
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 5, 0, 0, 0, 0, 0,
0,17, 2, 0, 0, 0, 0, 0,
0, 0, 5, 2, 0, 2, 2, 0,
0, 0, 0, 2, 2, 2, 0, 0,
0, 0, 0, 0,22, 0, 0, 0,
0, 0, 0,22, 0,21, 0, 0
Each frame of the animation is stored in an element in an array. I created functions to draw the image, starting at an xy coordinate. The animation function would move the xy co-ordinate in the desired direction then call the function to display the next frame.
I build my functions to be as modular as possible, then I build complexity by combining them. This allows me to work on “how to scroll the screen up and down” (using a loop and unicorn.get_pixels) one day, and work on "how can I give my space ship “vision” on the next. Add them together and I have a space ship that can see the rocks falling from the sky and use the same logic to have a car look for walls, and every 30 seconds the screen scrolls away and we get to see the time!
The truly impressive aspect is that I have to greatly slow down the animations. The Pi and the Unicorn are so blazingly fast that you can’t even see what is going on unless I keep everything throttled.
Oh, I look back on my single array of elements design as a case study for design flaws. Working with the sprites is about 20 times more complicated than it should be, but my design is at the very heart of the system so re-working it now would be extremely painful.
Do you manually convert the original artwork to sprites, or have a Python process to do it for you?
I often use GIMP/Photoshop to paint with a fixed palette into a PNG file, and then use pypng or PIL to process the result into sprite arrays, a bit like: https://github.com/pimoroni/unicorn-hat/blob/master/examples/hat/show_png.py
And a similar process to pack images of fonts (of a fixed width/height with fixed slot size for each character) into byte-arrays, like this for example: https://github.com/pimoroni/scroll-phat/blob/master/tools/mkfont.py
Hardcore. I do everything manually. I sketch out an idea on graph paper, then plot the array elements. The chicken took my son about 5 minutes, it only contains 3 frames. I have arrays of all zeros that I simply copy and past, then “draw” by filling in the appropriate numbers. It looks sort of like The Matrix. :)