# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries # # SPDX-License-Identifier: MIT import time import os import board import displayio from digitalio import DigitalInOut, Pull from adafruit_matrixportal.matrix import Matrix from adafruit_debouncer import Debouncer SPRITESHEET_FOLDER = "/bmps" DEFAULT_FRAME_DURATION = 0.1 # 100ms AUTO_ADVANCE_LOOPS = 3 FRAME_DURATION_OVERRIDES = { "three_rings1-sheet.bmp": 0.15, "hop1-sheet.bmp": 0.05, "firework1-sheet.bmp": 0.03, } # --- Display setup --- matrix = Matrix(bit_depth=4) sprite_group = displayio.Group() matrix.display.root_group = sprite_group # --- Button setup --- pin_down = DigitalInOut(board.BUTTON_DOWN) pin_down.switch_to_input(pull=Pull.UP) button_down = Debouncer(pin_down) pin_up = DigitalInOut(board.BUTTON_UP) pin_up.switch_to_input(pull=Pull.UP) button_up = Debouncer(pin_up) auto_advance = True file_list = sorted( [ f for f in os.listdir(SPRITESHEET_FOLDER) if (f.endswith(".bmp") and not f.startswith(".")) ] ) if len(file_list) == 0: raise RuntimeError("No images found") current_image = None current_frame = 0 current_loop = 0 frame_count = 0 frame_duration = DEFAULT_FRAME_DURATION def load_image(): """ Load an image as a sprite """ # pylint: disable=global-statement global current_frame, current_loop, frame_count, frame_duration while sprite_group: sprite_group.pop() filename = SPRITESHEET_FOLDER + "/" + file_list[current_image] # CircuitPython 6 & 7 compatible bitmap = displayio.OnDiskBitmap(open(filename, "rb")) sprite = displayio.TileGrid( bitmap, pixel_shader=getattr(bitmap, 'pixel_shader', displayio.ColorConverter()), tile_width=bitmap.width, tile_height=matrix.display.height, ) # # CircuitPython 7+ compatible # bitmap = displayio.OnDiskBitmap(filename) # sprite = displayio.TileGrid( # bitmap, # pixel_shader=bitmap.pixel_shader, # tile_width=bitmap.width, # tile_height=matrix.display.height, # ) sprite_group.append(sprite) current_frame = 0 current_loop = 0 frame_count = int(bitmap.height / matrix.display.height) frame_duration = DEFAULT_FRAME_DURATION if file_list[current_image] in FRAME_DURATION_OVERRIDES: frame_duration = FRAME_DURATION_OVERRIDES[file_list[current_image]] def advance_image(): """ Advance to the next image in the list and loop back at the end """ # pylint: disable=global-statement global current_image if current_image is not None: current_image += 1 if current_image is None or current_image >= len(file_list): current_image = 0 load_image() def advance_frame(): """ Advance to the next frame and loop back at the end """ # pylint: disable=global-statement global current_frame, current_loop current_frame = current_frame + 1 if current_frame >= frame_count: current_frame = 0 current_loop = current_loop + 1 sprite_group[0][0] = current_frame advance_image() while True: if auto_advance and current_loop >= AUTO_ADVANCE_LOOPS: advance_image() button_down.update() button_up.update() if button_up.fell: auto_advance = not auto_advance if button_down.fell: advance_image() advance_frame() time.sleep(frame_duration)