Adafruit_Learning_System_Gu.../Matrix_Sprite_Animation_Player/code.py
2023-11-06 11:55:54 -06:00

132 lines
3.4 KiB
Python

# 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)