The Match3 game makes use of the new tilepalettemapper
core module which was added in CircuitPython 9.2.5. You must update your device if its version of CircuitPython is 9.2.4 or older. It is generally recommended to run the latest stable version of CircuitPython.
This demo program will illustrate how tilepalettemapper
works and how the Match3 game code uses it to have one set of card sprites and re-map them to the 3 different possible colors, instead of needing one sprite for each of the different colors which would mean needing 3x as many sprites.
There are a few important things to note about the spritesheet:
- The sprites are arranged into a 7x4 grid of tiles. There are 28 total sprites in the full sheet.
- 27 of the sprites are Match3 game cards. Do not worry about the different shapes and types just yet, they'll be used by the game but aren't important to this demo.
- All of the game card sprites have a white background with black foreground pixels, drawing its shape and fill type.
- The last sprite in the bottom right corner isn't a game card. It has 3 small colored blocks within it. Those 3 colors are the possible colors that the cards will get mapped to when drawn on the display: red, green, and purple. Any pixel in a card that is black in the spritesheet will be mapped one of those other 3 colors when shown with a
TileGrid
.
This is the palette for the spritesheet image. It contains the following colors at their respective indexes.
- 0: white
- 1: black
- 2: purple
- 3: red
- 4: green
The TilePaletteMapper
object maps the indexes within the palette for each tile within a TileGrid
to different chosen indexes. For the Match3 game, and in this demo script the code maps index 1
to use one of indexes 2
, 3
, or 4
. Since black is at index 1
and the card designs are drawn in black in the spritesheet, this will have the effect of changing the card to either purple, red, or green depending on which index is chosen for the mapping.
Demo Code
The demo code is shown below followed by a screenshot of the cards that it displays. If you want to run it on your own device click the "Download Project Bundle" button, unzip the project files and copy them to the CIRCUITPY drive.
# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries # # SPDX-License-Identifier: MIT import sys import supervisor from displayio import Group, OnDiskBitmap, TileGrid from tilepalettemapper import TilePaletteMapper # use the default built-in display, # the HSTX / PicoDVI display for the Metro RP2350 display = supervisor.runtime.display # a group to hold all other visual elements main_group = Group(scale=4, x=30, y=30) # set the main group to show on the display display.root_group = main_group # load the sprite sheet bitmap spritesheet_bmp = OnDiskBitmap("match3_cards_spritesheet.bmp") # create a TilePaletteMapper if sys.implementation.version[0] == 9: tile_palette_mapper = TilePaletteMapper( spritesheet_bmp.pixel_shader, # input pixel_shader 5, # input color count 3, # grid width 1, # grid height ) elif sys.implementation.version[0] >= 10: tile_palette_mapper = TilePaletteMapper( spritesheet_bmp.pixel_shader, # input pixel_shader 5, # input color count ) # create a TileGrid to show some cards cards_tilegrid = TileGrid( spritesheet_bmp, pixel_shader=tile_palette_mapper, width=3, height=1, tile_width=24, tile_height=32, ) # set each tile in the grid to a different sprite index cards_tilegrid[0, 0] = 10 cards_tilegrid[1, 0] = 25 cards_tilegrid[2, 0] = 2 # re-map each tile in the grid to use a different color for index 1 # all other indexes remain their default values tile_palette_mapper[0, 0] = [0, 2, 2, 3, 4] tile_palette_mapper[1, 0] = [0, 3, 2, 3, 4] tile_palette_mapper[2, 0] = [0, 4, 2, 3, 4] # add the tilegrid to the main group main_group.append(cards_tilegrid) # wait forever so it remains visible on the display while True: pass
TilePaletteMapper Usage
The code creates a TilePalleteMapper
instance, supplying an input color count, grid width, and grid height as arguments.
tile_palette_mapper = TilePaletteMapper( spritesheet_bmp.pixel_shader, # input pixel_shader 5, # input color count 3, # grid width 1 # grid height )
tile_palette_mapper
is then used as the pixel_shader
for a TileGrid
cards_tilegrid = TileGrid(spritesheet_bmp, pixel_shader=tile_palette_mapper, width=3, height=1, tile_width=24, tile_height=32)
To re-map the colors the code sets new color index lists at the desired tile locations.
# re-map each tile in the grid to use a different color for index 1 # all other indexes remain their default values tile_palette_mapper[0, 0] = [0, 2, 2, 3, 4] tile_palette_mapper[1, 0] = [0, 3, 2, 3, 4] tile_palette_mapper[2, 0] = [0, 4, 2, 3, 4]
To change the foreground color of each card a new color index is supplied for the second value in the list. By default it would be index 1
to match its own index within the list. The code sets the 3 different tile positions to 2
, 3
, and 4
which are the indexes for purple, red, and green respectively.
Page last edited April 14, 2025
Text editor powered by tinymce.