Last active
August 14, 2021 23:49
-
-
Save todbot/92373f93db9da0fca5ca4adee8d7d75b to your computer and use it in GitHub Desktop.
fake Almost Asteroids, using CircuitPython and displayio.TileGrid()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# staroids_tilegrid_code.py -- fakey Almost Asteroids | |
# 4 Aug 2021 - @todbot | |
import board, time, math, random | |
import displayio, terminalio, bitmaptools | |
import adafruit_imageload | |
import digitalio | |
num_roids = 4 # how many asteroids do you want | |
button_L = digitalio.DigitalInOut(board.BUTTON_UP) # turn left | |
button_L.switch_to_input(pull=digitalio.Pull.DOWN) | |
button_R = digitalio.DigitalInOut(board.BUTTON_DOWN) # turn right | |
button_R.switch_to_input(pull=digitalio.Pull.DOWN) | |
button_F = digitalio.DigitalInOut(board.BUTTON_SELECT) # thrust! | |
button_F.switch_to_input(pull=digitalio.Pull.DOWN) | |
display = board.DISPLAY | |
display.auto_refresh=False | |
screen = displayio.Group() # group that holds everything | |
display.show(screen) # add main group to display | |
# helper object for physics things | |
class Thing: | |
def __init__(self, x,y, vx,vy, angle, va=0, tilegrid=None, num_tiles=1): | |
self.x, self.y = x,y | |
self.vx,self.vy = vx,vy | |
self.angle = angle | |
self.va = va # default angular velocity | |
self.vmax = 2 # maximum velocity | |
self.tg = tilegrid | |
self.num_tiles = num_tiles | |
def accelerate(self,angle, amount): | |
self.vx = min(self.vmax, self.vx + (math.sin(angle) * amount) ) | |
self.vy = min(self.vmax, self.vy - (math.cos(angle) * amount) ) | |
def update_pos(self, alt_sprite_index=0): | |
self.x, self.y = self.x + self.vx, self.y + self.vy | |
self.tg.x = int(self.x) % display.width | |
self.tg.y = int(self.y) % display.height # hmmm not self-contained | |
self.angle += self.va | |
# get a tilegrid index based on angle and number of tiles total | |
i = int(math.degrees(self.angle) / (360 / self.num_tiles)) % self.num_tiles | |
self.tg[0] = i + (alt_sprite_index * self.num_tiles) | |
# get ship sprites | |
num_ship_tiles = 36 | |
ship_sprites,ship_sprites_pal = adafruit_imageload.load('ship-all.bmp') | |
ship_sprites_pal.make_transparent(0) | |
shiptg = displayio.TileGrid(ship_sprites, pixel_shader=ship_sprites_pal, | |
width=1, height=1, tile_width=30, tile_height=30) | |
# get asteroid sprites | |
num_roid_tiles = 120 # tiles per image | |
roid_spr_pal = [] | |
for f in ['roid0-all.bmp','roid1-all.bmp']: | |
spr,pal = adafruit_imageload.load(f) | |
pal.make_transparent(0) | |
roid_spr_pal.append( (spr,pal) ) | |
##get background image, hubble star field | |
bgimg, bgpal = adafruit_imageload.load("bg_starfield.bmp") | |
screen.append(displayio.TileGrid(bgimg, pixel_shader=bgpal)) | |
# create ship object | |
ship = Thing( display.width/2, display.height/2, 0.5, 0.2, 0, va=0, | |
tilegrid=shiptg, num_tiles=num_ship_tiles) | |
# create all the asteroids, add them to the screen | |
roids = [] | |
for i in range(num_roids): | |
vx,vy = random.uniform(-1,1), random.uniform(-1,1) | |
spr,pal = roid_spr_pal[ i % len(roid_spr_pal) ] | |
roidtg = displayio.TileGrid(spr, pixel_shader=pal, | |
width=1, height=1, tile_width=30, tile_height=30) | |
va = random.choice((-0.01,0.01)) # either rotate a little one way or other | |
roid = Thing(display.width/2, display.height/2, vx,vy, 0, va=va, | |
tilegrid=roidtg, num_tiles=num_roid_tiles) | |
roids.append(roid) | |
screen.append(roid.tg) | |
# finally add our ship to the screen | |
screen.append(ship.tg) | |
last_debug_time = 0 | |
while True: | |
# check on the user | |
if button_L.value: # rotate left | |
ship.angle = ship.angle - 0.1 | |
if button_R.value: # rotate right | |
ship.angle = ship.angle + 0.1 | |
if button_F.value: # thrust! | |
ship.accelerate( ship.angle, 0.1) | |
# update ship position | |
ship.update_pos( button_F.value ) | |
# update asteroids | |
for roid in roids: | |
roid.update_pos() | |
display.refresh(target_frames_per_second=60) | |
# time.sleep(0.0015) # sets framerate | |
# debug | |
if time.monotonic() - last_debug_time > 0.2: | |
roid = roids[0] | |
print("roid0:",roid.x,roid.y, roid.vx,roid.vy, roid.angle, roid.tg[0]) | |
last_debug_time = time.monotonic() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks @dglaude!