Skip to content

Commit 6462fd2

Browse files
committed
Add flying toaster code
1 parent 7f74afa commit 6462fd2

2 files changed

Lines changed: 179 additions & 0 deletions

File tree

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
"""
2+
Continuously scroll randomly generated Mario style toasters.
3+
Designed fr an ItsyBitsy M4 Express and a 1.3" 240x240 TFT
4+
5+
Adafruit invests time and resources providing this open source code.
6+
Please support Adafruit and open source hardware by purchasing
7+
products from Adafruit!
8+
9+
Written by Dave Astels for Adafruit Industries
10+
Copyright (c) 2019 Adafruit Industries
11+
Licensed under the MIT license.
12+
13+
All text above must be included in any redistribution.
14+
"""
15+
16+
import time
17+
from random import seed, randint
18+
import board
19+
import displayio
20+
from adafruit_st7789 import ST7789
21+
import adafruit_imageload
22+
23+
24+
# Sprite cell values
25+
EMPTY = 0
26+
CELL_1 = EMPTY + 1
27+
CELL_2 = CELL_1 + 1
28+
CELL_3 = CELL_2 + 1
29+
CELL_4 = CELL_3 + 1
30+
TOAST = CELL_4 + 1
31+
32+
NUMBER_OF_SPRITES = TOAST + 1
33+
34+
# Animation support
35+
36+
FIRST_CELL = CELL_1
37+
LAST_CELL = CELL_4
38+
39+
NUMBER_OF_CELLS = (LAST_CELL - FIRST_CELL) + 1
40+
41+
# A boolean array corresponding to the sprites, True if it's part of the animation sequence.
42+
ANIMATED = [_sprite >= FIRST_CELL and _sprite <= LAST_CELL for _sprite in range(NUMBER_OF_SPRITES)]
43+
44+
45+
# The chance (out of 10) that a new toaster, or toast will enter
46+
CHANCE_OF_NEW_TOASTER = 5
47+
CHANCE_OF_NEW_TOAST = 2
48+
49+
# How many sprites to styart with
50+
INITIAL_NUMBER_OF_SPRITES= 5
51+
52+
# Global variables
53+
display = None
54+
tilegrid = None
55+
56+
seed(int(time.monotonic()))
57+
58+
def make_display():
59+
"""Set up the display support.
60+
Return the Display object.
61+
"""
62+
spi = board.SPI()
63+
while not spi.try_lock():
64+
pass
65+
spi.configure(baudrate=24000000) # Configure SPI for 24MHz
66+
spi.unlock()
67+
tft_cs = board.D10
68+
tft_dc = board.D7
69+
70+
displayio.release_displays()
71+
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=board.D9)
72+
73+
return ST7789(display_bus, width=240, height=240, rowstart=80, auto_refresh=True)
74+
75+
def make_tilegrid():
76+
"""Construct and return the tilegrid."""
77+
group = displayio.Group(max_size=10)
78+
79+
sprite_sheet, palette = adafruit_imageload.load("/spritesheet.bmp",
80+
bitmap=displayio.Bitmap,
81+
palette=displayio.Palette)
82+
grid = displayio.TileGrid(sprite_sheet, pixel_shader=palette,
83+
width=9, height=9,
84+
tile_height=32, tile_width=32,
85+
x=0, y=-32,
86+
default_tile=EMPTY)
87+
group.append(grid)
88+
display.show(group)
89+
return grid
90+
91+
def random_cell():
92+
return randint(FIRST_CELL, LAST_CELL)
93+
94+
def evaluate_position(row, col):
95+
"""Return whether how long of aa toaster is placable at the given location.
96+
:param row: the tile row (0-9)
97+
:param col: the tile column (0-9)
98+
"""
99+
return tilegrid[col, row] == EMPTY
100+
101+
def seed_toasters(number_of_toasters):
102+
"""Create the initial toasters so it doesn't start empty"""
103+
for _ in range(number_of_toasters):
104+
while True:
105+
row = randint(0, 8)
106+
col = randint(0, 8)
107+
if evaluate_position(row, col):
108+
break
109+
tilegrid[col, row] = random_cell()
110+
111+
def next_sprite(sprite):
112+
if ANIMATED[sprite]:
113+
return (((sprite - FIRST_CELL) + 1) % NUMBER_OF_CELLS) + FIRST_CELL
114+
return sprite
115+
116+
def advance_animation():
117+
"""Cycle through animation cells each time."""
118+
for tile_number in range(81):
119+
tilegrid[tile_number] = next_sprite(tilegrid[tile_number])
120+
121+
def slide_tiles():
122+
"""Move the tilegrid one pixel to the bottom-left."""
123+
tilegrid.x -= 1
124+
tilegrid.y += 1
125+
126+
def shift_tiles():
127+
"""Move tiles one spot to the left, and reset the tilegrid's position"""
128+
for row in range(8, 0, -1):
129+
for col in range(8):
130+
tilegrid[col, row] = tilegrid[col + 1, row - 1]
131+
tilegrid[8, row] = EMPTY
132+
for col in range(9):
133+
tilegrid[col, 0] = EMPTY
134+
tilegrid.x = 0
135+
tilegrid.y = -32
136+
137+
def get_entry_row():
138+
while True:
139+
row = randint(0, 8)
140+
if tilegrid[8, row] == EMPTY and tilegrid[7, row] == EMPTY:
141+
return row
142+
143+
def get_entry_column():
144+
while True:
145+
col = randint(0, 8)
146+
if tilegrid[col, 0] == EMPTY and tilegrid[col, 1] == EMPTY:
147+
return col
148+
149+
def add_toaster_or_toast():
150+
"""Maybe add a new toaster or toast on the right and/or top at a randon open location"""
151+
if randint(1, 10) <= CHANCE_OF_NEW_TOAST:
152+
tile = TOAST
153+
elif randint(1, 10) <= CHANCE_OF_NEW_TOASTER:
154+
tile = random_cell()
155+
else:
156+
tile = EMPTY
157+
tilegrid[8, get_entry_row()] = tile
158+
159+
if randint(1, 10) <= CHANCE_OF_NEW_TOAST:
160+
tile = TOAST
161+
elif randint(1, 8) <= CHANCE_OF_NEW_TOASTER:
162+
tile = random_cell()
163+
else:
164+
tile = EMPTY
165+
tilegrid[get_entry_column(), 0] = tile
166+
167+
display = make_display()
168+
tilegrid = make_tilegrid()
169+
seed_toasters(INITIAL_NUMBER_OF_SPRITES)
170+
display.refresh()
171+
172+
while True:
173+
for _ in range(32):
174+
display.refresh(target_frames_per_second=80)
175+
advance_animation()
176+
slide_tiles()
177+
shift_tiles()
178+
add_toaster_or_toast()
179+
display.refresh(target_frames_per_second=120)
9.12 KB
Binary file not shown.

0 commit comments

Comments
 (0)