Prerequisite: Displayio.TileGrid
All of the graphics in this game are based on the displayio
core CircuitPython API which is largely centered around the TileGrid
class. In our game, the map world is a TileGrid
, the Player and Ghost are also their own individual 1x1 sized TileGrids. As such, it will be easier to understand how the code within the game and its helper classes work if you've already read through the basics of TileGrids over in the main Displayio Learn Guide. It's not a super-long read, so if you haven't already, head there and give it a read over, then come back to here.
Entering the 4th Dimension
While our game map is only a single dimension, the animations we want to use within it are most dependent on the 4th dimension: Time. To achieve animations we simply show a frame of our animation, then wait a little bit of time and show the next frame, repeating the process until there are no more frames to show, then start over at the beginning. I like to think of it like a flip book made with a stack of paper with slightly different drawings on each page. As the pages are flipped our eyes and brains work together to create the visual appearance of relatively smooth motion out of the different frames visible on each page.
The animations used in 1D Chomper are very basic, just 2 frames each. However the same technique can be used on animations with more frames just as easily.
Changing Image Sprites within a TileGrid
In this game the Player and the Ghost are the two things that have animations. The player chomps it's mouth up and down, the Ghost flickers between blue and white to warn the user when the effects of the ghost subduing large pellet is about to wear off.
Once a TileGrid is initialized with a sprite sheet, changing the image that is showing is as simple as modifying the index at an x,y location within the TileGrid. Our Player and Ghost TileGrid's are 1x1 sized so the only x,y coordinate pair they contain is 0,0
the indexes represent the index within the spritesheet. Illustration shows the indexes labeled next to an enlarged copy of the spritesheet:
Player and Ghost Animations
For the player chomping animation, the sprites we use depends on the direction the Player is moving. When moving right we cycle between sprites 0 and 5. When the moving left instead we cycle between sprites 2 and 7.
The Ghost animation blinks between the blue and white versions of the ghost which are sprites 18 and 19.
Example Code
This code shows a minimal self-contained example of creating and animating sprites with TileGrid:
""" Tilegrid Animation Example """ import time from adafruit_qualia import Qualia from adafruit_qualia.graphics import Displays import displayio import adafruit_imageload ANIMATION_DELAY = 0.15 # seconds last_animation_time = 0 # Create the Qualia object for the 240x960 display PID 5799 qualia = Qualia(Displays.BAR240X960) # OR create the Qualia object for the 320x960 display PID 5805 # qualia = Qualia(Displays.BAR320X960) display = qualia.display # Landscape orientation, mounted with ribbon cable coming off the left side of display. display.rotation = 270 # scaled group to put our tilegrid in for showing on the display main_group = displayio.Group(scale=5) main_group.x = 100 main_group.y = 50 spritesheet_bmp, spritesheet_palette = adafruit_imageload.load("1d_chomper_spritesheet.bmp") spritesheet_palette.make_transparent(0) animation_example_tg = displayio.TileGrid(bitmap=spritesheet_bmp, pixel_shader=spritesheet_palette, width=1, height=1, tile_width=15, tile_height=15, default_tile=0) current_sprite = 0 main_group.append(animation_example_tg) display.root_group = main_group # main loop while True: now = time.monotonic() # if it's been long enough since previous frame if now > last_animation_time + ANIMATION_DELAY: last_animation_time = now # alternate sprites if current_sprite == 0: current_sprite = 5 else: current_sprite = 0 # update the sprite index in the tilegrid animation_example_tg[0, 0] = current_sprite
In the 1D Chomper game code this animation functionality is encapsulated within helper classes described on the next page.
Text editor powered by tinymce.