Skip to content

Instantly share code, notes, and snippets.

@todbot
Created March 30, 2022 01:58
Show Gist options
  • Save todbot/067b0ad68ffccdce077f8ed42f5f89d2 to your computer and use it in GitHub Desktop.
Save todbot/067b0ad68ffccdce077f8ed42f5f89d2 to your computer and use it in GitHub Desktop.
playing with palette animation in CircuitPython
# beachball_bounce.py -- playing with palette animation
# 29 Mar 2022 - @todbot / Tod Kurt
# Tested on ESP32-S2 Feather, but doesn't require it
# Needs "pinwheel_30.bmp", a 30x30 8-color pinwheel, where color0 is background
# created with ImageMagick:
# convert pinwheel.png -resize 30x30 -colors 8 -type palette -compress None BMP3:pinwheel_30.bmp
import time
import board
import displayio
import random
display = board.DISPLAY
display.auto_refresh=True
maingroup = displayio.Group()
display.show(maingroup) # put main group on display, everything goes in maingroup
yaccel = 0.1
yaccel_max = 3.2
num_balls = 5
ball_w = 30
balls = [None] * num_balls # holds the ball Tile_Grid objects w/ x,y
ball_pos = [(0,0,0,0,)] * num_balls # holds ball position & acceleration (xvel, yvel, xaccel, yaccel)
for i in range(num_balls):
# bmp balls
bitmap = displayio.OnDiskBitmap(open("/pinwheel_30.bmp", "rb"))
pal = bitmap.pixel_shader
pal.make_transparent(0)
balls[i] = displayio.TileGrid(bitmap, pixel_shader=pal)
ball_pos[i] = (30,30, 1+random.random()*3, random.random()*3 )
maingroup.append(balls[i])
def rotate_palette(pal):
tmp = pal[7] # save topmost color
for i in range(8, 0, -1):
pal[i+1] = pal[i] # move all colors up
pal[1] = tmp # add back saved color (pal[0] is transparent)
last_weird_time = time.monotonic()
while True:
for i in range(num_balls):
(x,y,xvel,yvel) = ball_pos[i]
x = x + xvel
y = y + yvel
yvel = min(yvel + yaccel, yaccel_max) # add "gravity"
# if we hit an edge, bounce & change color!
if x < 0 or x > (display.width - ball_w):
xvel = -xvel
yvel = yvel - yaccel_max/2 # add a little spice
if y > (display.height - ball_w):
yvel = -yvel
balls[i].x = int(x)
balls[i].y = int(y)
ball_pos[i] = (x,y,xvel,yvel) # save position & velocity for next time
if time.monotonic() - last_weird_time > 0.1:
last_weird_time = time.monotonic()
for i in range(num_balls):
rotate_palette( balls[i].pixel_shader )
display.refresh( target_frames_per_second = 60 )
time.sleep(0.001)
@todbot
Copy link
Author

todbot commented Mar 30, 2022

The image used
pinwheel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment