Here's a breakdown of how the dreidel code works. The use of a sprite sheet along with group scaling for the symbols is probably the most interesting from a displayio aspect. But we'll go over all the code.
First, a static background image is used to represent the dreidel itself. It looks like this full size:
Note it is 240x240 pixels, since that's the size of the TFT Gizmo display.
Then, we define a face area where the symbols will go: The area is 120x120 pixels and is located at x=60, y=70.
There's nothing needed in code for this definition. This is just a convention that will be used for setting up the symbols.
Now for the fun part. There are four symbols to deal with. We could have four separate 120x120 pixel images for each. But then we have all those separate files to keep track of and deal with. A better approach is to use the idea of a sprite sheet. This will let us have only a single file to deal with. The sprite sheet will contain the four symbols and each symbol will be a separate sprite.
That's the approach taken here. The dreidel symbol sprite sheet looks like this:
Further, the dreidel symbols are fairly simple graphics-wise. Our target size is 120x120 pixels, but we really don't need to define the symbols at that resolution. We can get away with defining them at half that, so 60x60 pixels, and then use the scale feature of the displayio Group to have them render at the desired 120x120 pixels, by setting
So our actual sprite sheet will look like this:
Each of the four symbols is only 60x60 pixels. The overall size of the entire sprite sheet ends up being 120x120 pixels. Here's what it looks like full size:
The yellow background is used so we can easily find that when the image is loaded and set that palette index to be transparent.
The melody definition is pretty straight forward. Just define the frequency and duration for each note. Then loop through each of those and use
play_tone() to play them.
But how do we play the melody while also updating the symbols on the display? Well, it turns out we can get away with something very simple. Since we went to the trouble to define the symbols very small and then scale them at render time, they load pretty darn fast. So fast in fact that we can just add a call to reload a different symbol within the loop that plays the melody. The display updates without noticeably slowing down the melody playback. Neat!
The whole thing is kicked off by waiting for the board to be shaken. So, shake to "spin" the dreidel. Then, after the melody, a random symbol is shown. And then it just loops back to the start and waits for a shake again.