@@ -31,19 +31,19 @@ def background_sound(filename):
31
31
""" Start a WAV file playing in the background (non-blocking). This
32
32
func can be removed if/when MacroPad lib gets background audio. """
33
33
# pylint: disable=protected-access
34
- MACROPAD ._speaker_enable .value = True
35
- AUDIO .play (audiocore .WaveFile (open (PATH + filename , 'rb' )))
34
+ macropad ._speaker_enable .value = True
35
+ audio .play (audiocore .WaveFile (open (PATH + filename , 'rb' )))
36
36
37
37
def show_screen (group ):
38
38
""" Activate a given displayio group, pause until keypress. """
39
- MACROPAD .display .show (group )
40
- MACROPAD .display .refresh ()
39
+ macropad .display .show (group )
40
+ macropad .display .refresh ()
41
41
# Purge any queued up key events...
42
- while MACROPAD .keys .events .get ():
42
+ while macropad .keys .events .get ():
43
43
pass
44
44
while True : # ...then wait for first new key press event
45
- event = MACROPAD .keys .events .get ()
46
- if event and event .pressed :
45
+ key_event = macropad .keys .events .get ()
46
+ if key_event and key_event .pressed :
47
47
return
48
48
49
49
# pylint: disable=too-few-public-methods
@@ -58,228 +58,228 @@ def __init__(self, col, start_time):
58
58
59
59
# ONE-TIME INITIALIZATION --------------
60
60
61
- MACROPAD = MacroPad (rotation = 90 )
62
- MACROPAD .display .auto_refresh = False
63
- MACROPAD .pixels .auto_write = False
64
- MACROPAD .pixels .brightness = 0.5
65
- AUDIO = audiopwmio .PWMAudioOut (board .SPEAKER ) # For background audio
61
+ macropad = MacroPad (rotation = 90 )
62
+ macropad .display .auto_refresh = False
63
+ macropad .pixels .auto_write = False
64
+ macropad .pixels .brightness = 0.5
65
+ audio = audiopwmio .PWMAudioOut (board .SPEAKER ) # For background audio
66
66
67
- FONT = bitmap_font .load_font (PATH + 'cursive-smart.pcf' )
67
+ font = bitmap_font .load_font (PATH + 'cursive-smart.pcf' )
68
68
69
69
# Create 3 displayio groups -- one each for the title, play and end screens.
70
70
71
- TITLE_GROUP = displayio .Group ()
72
- TITLE_BITMAP , TITLE_PALETTE = adafruit_imageload .load (PATH + 'title.bmp' ,
71
+ title_group = displayio .Group ()
72
+ title_bitmap , title_palette = adafruit_imageload .load (PATH + 'title.bmp' ,
73
73
bitmap = displayio .Bitmap ,
74
74
palette = displayio .Palette )
75
- TITLE_GROUP .append (displayio .TileGrid (TITLE_BITMAP , pixel_shader = TITLE_PALETTE ,
75
+ title_group .append (displayio .TileGrid (title_bitmap , pixel_shader = title_palette ,
76
76
width = 1 , height = 1 ,
77
- tile_width = TITLE_BITMAP .width ,
78
- tile_height = TITLE_BITMAP .height ))
77
+ tile_width = title_bitmap .width ,
78
+ tile_height = title_bitmap .height ))
79
79
80
80
# Bitmap containing eggs, hatchling and fireballs
81
- SPRITE_BITMAP , SPRITE_PALETTE = adafruit_imageload .load (
81
+ sprite_bitmap , sprite_palette = adafruit_imageload .load (
82
82
PATH + 'sprites.bmp' , bitmap = displayio .Bitmap , palette = displayio .Palette )
83
- SPRITE_PALETTE .make_transparent (0 )
83
+ sprite_palette .make_transparent (0 )
84
84
85
- PLAY_GROUP = displayio .Group ()
85
+ play_group = displayio .Group ()
86
86
# Bitmap containing five shadow tiles ('no shadow' through 'max shadow')
87
- SHADOW_BITMAP , SHADOW_PALETTE = adafruit_imageload .load (
87
+ shadow_bitmap , shadow_palette = adafruit_imageload .load (
88
88
PATH + 'shadow.bmp' , bitmap = displayio .Bitmap , palette = displayio .Palette )
89
89
# Tilegrid with four shadow tiles; one per column
90
- SHADOW = displayio .TileGrid (SHADOW_BITMAP , pixel_shader = SHADOW_PALETTE ,
90
+ shadow = displayio .TileGrid (shadow_bitmap , pixel_shader = shadow_palette ,
91
91
width = 4 , height = 1 , tile_width = 16 ,
92
- tile_height = SHADOW_BITMAP .height , x = 0 ,
93
- y = MACROPAD .display .height - SHADOW_BITMAP .height )
94
- PLAY_GROUP .append (SHADOW )
95
- SHADOW_SCALE = 5 / (MACROPAD .display .height - 20 ) # For picking shadow sprite
96
- LIFE_BAR = HorizontalProgressBar ((0 , 0 ), (MACROPAD .display .width , 7 ),
92
+ tile_height = shadow_bitmap .height , x = 0 ,
93
+ y = macropad .display .height - shadow_bitmap .height )
94
+ play_group .append (shadow )
95
+ shadow_scale = 5 / (macropad .display .height - 20 ) # For picking shadow sprite
96
+ life_bar = HorizontalProgressBar ((0 , 0 ), (macropad .display .width , 7 ),
97
97
value = 100 , min_value = 0 , max_value = 100 ,
98
98
bar_color = 0xFFFFFF , outline_color = 0xFFFFFF ,
99
99
fill_color = 0 , margin_size = 1 )
100
- PLAY_GROUP .append (LIFE_BAR )
101
- # Score is last object in PLAY_GROUP , can be indexed as -1
102
- PLAY_GROUP .append (label .Label (FONT , text = '0' , color = 0xFFFFFF ,
100
+ play_group .append (life_bar )
101
+ # Score is last object in play_group , can be indexed as -1
102
+ play_group .append (label .Label (font , text = '0' , color = 0xFFFFFF ,
103
103
anchor_point = (0.5 , 0.0 ),
104
- anchored_position = (MACROPAD .display .width // 2 ,
104
+ anchored_position = (macropad .display .width // 2 ,
105
105
10 )))
106
106
107
- END_GROUP = displayio .Group ()
108
- END_BITMAP , END_PALETTE = adafruit_imageload .load (
107
+ end_group = displayio .Group ()
108
+ end_bitmap , end_palette = adafruit_imageload .load (
109
109
PATH + 'gameover.bmp' , bitmap = displayio .Bitmap , palette = displayio .Palette )
110
- END_GROUP .append (displayio .TileGrid (END_BITMAP , pixel_shader = END_PALETTE ,
110
+ end_group .append (displayio .TileGrid (end_bitmap , pixel_shader = end_palette ,
111
111
width = 1 , height = 1 ,
112
- tile_width = END_BITMAP .width ,
113
- tile_height = END_BITMAP .height ))
114
- END_GROUP .append (label .Label (FONT , text = '0' , color = 0xFFFFFF ,
112
+ tile_width = end_bitmap .width ,
113
+ tile_height = end_bitmap .height ))
114
+ end_group .append (label .Label (font , text = '0' , color = 0xFFFFFF ,
115
115
anchor_point = (0.5 , 0.0 ),
116
- anchored_position = (MACROPAD .display .width // 2 ,
116
+ anchored_position = (macropad .display .width // 2 ,
117
117
90 )))
118
118
119
119
120
120
# MAIN LOOP -- alternates play and end-game screens --------
121
121
122
- show_screen (TITLE_GROUP ) # Just do this once on startup
122
+ show_screen (title_group ) # Just do this once on startup
123
123
124
124
while True :
125
125
126
126
# NEW GAME -------------------------
127
127
128
- SPRITES = []
129
- SCORE = 0
130
- PLAY_GROUP [- 1 ].text = '0' # Score text
131
- LIFE_BAR .value = 100
132
- AUDIO .stop ()
133
- MACROPAD .display .show (PLAY_GROUP )
134
- MACROPAD .display .refresh ()
135
- START_TIME = time .monotonic ()
128
+ sprites = []
129
+ score = 0
130
+ play_group [- 1 ].text = '0' # Score text
131
+ life_bar .value = 100
132
+ audio .stop ()
133
+ macropad .display .show (play_group )
134
+ macropad .display .refresh ()
135
+ start = time .monotonic ()
136
136
137
137
# PLAY UNTIL LIFE BAR DEPLETED -----
138
138
139
- while LIFE_BAR .value > 0 :
140
- NOW = time .monotonic ()
141
- SPEED = 10 + (NOW - START_TIME ) / 30 # Gradually speed up
142
- FIRE_SPRITE = 3 + int ((NOW * 6 ) % 2.0 ) # For animating fire
139
+ while life_bar .value > 0 :
140
+ now = time .monotonic ()
141
+ speed = 10 + (now - start ) / 30 # Gradually speed up
142
+ fire_sprite = 3 + int ((now * 6 ) % 2.0 ) # For animating fire
143
143
144
144
# Coalese any/all queued-up keypress events per column
145
- COLUMN_PRESSED = [False ] * 4
145
+ column_pressed = [False ] * 4
146
146
while True :
147
- EVENT = MACROPAD .keys .events .get ()
148
- if not EVENT :
147
+ event = macropad .keys .events .get ()
148
+ if not event :
149
149
break
150
- if EVENT .pressed :
151
- COLUMN_PRESSED [ EVENT .key_number % 4 ] = True
150
+ if event .pressed :
151
+ column_pressed [ event .key_number % 4 ] = True
152
152
153
153
# For determining upper/lower extents of active egg sprites per column
154
- COLUMN_MIN = [MACROPAD .display .height ] * 4
155
- COLUMN_MAX = [0 ] * 4
154
+ column_min = [macropad .display .height ] * 4
155
+ column_max = [0 ] * 4
156
156
157
157
# Traverse sprite list backwards so we can pop() without index problems
158
- for i in range (len (SPRITES ) - 1 , - 1 , - 1 ):
159
- sprite = SPRITES [i ]
160
- tile = PLAY_GROUP [i + 1 ] # Corresponding 1x1 TileGrid for sprite
158
+ for i in range (len (sprites ) - 1 , - 1 , - 1 ):
159
+ sprite = sprites [i ]
160
+ tile = play_group [i + 1 ] # Corresponding 1x1 TileGrid for sprite
161
161
column = sprite .column
162
- elapsed = NOW - sprite .start_time # Time since add or pause event
162
+ elapsed = now - sprite .start_time # Time since add or pause event
163
163
164
164
if sprite .is_fire :
165
- tile [0 ] = FIRE_SPRITE # Animate all flame sprites
165
+ tile [0 ] = fire_sprite # Animate all flame sprites
166
166
167
167
if sprite .paused : # Sprite at bottom of screen
168
168
if elapsed > 0.75 : # Hold position for 3/4 second,
169
169
for x in range (0 , 9 , 4 ): # then LEDs off,
170
- MACROPAD .pixels [x + sprite .column ] = (0 , 0 , 0 )
171
- SPRITES .pop (i ) # and delete Sprite object and
172
- PLAY_GROUP .pop (i + 1 ) # element from displayio group
170
+ macropad .pixels [x + sprite .column ] = (0 , 0 , 0 )
171
+ sprites .pop (i ) # and delete Sprite object and
172
+ play_group .pop (i + 1 ) # element from displayio group
173
173
continue
174
174
if not sprite .is_fire :
175
- COLUMN_MAX [column ] = max (COLUMN_MAX [column ],
176
- MACROPAD .display .height - 22 )
175
+ column_max [column ] = max (column_max [column ],
176
+ macropad .display .height - 22 )
177
177
else : # Sprite in motion
178
- y = SPEED * elapsed * elapsed - 16
178
+ y = speed * elapsed * elapsed - 16
179
179
# Track top of all sprites, bottom of eggs only
180
- COLUMN_MIN [column ] = min (COLUMN_MIN [column ], y )
180
+ column_min [column ] = min (column_min [column ], y )
181
181
if not sprite .is_fire :
182
- COLUMN_MAX [column ] = max (COLUMN_MAX [column ], y )
183
- tile .y = int (y ) # Sprite's vertical pos. in PLAY_GROUP
182
+ column_max [column ] = max (column_max [column ], y )
183
+ tile .y = int (y ) # Sprite's vertical pos. in play_group
184
184
185
185
# Handle various catch or off-bottom actions...
186
186
if sprite .is_fire :
187
- if y >= MACROPAD .display .height : # Off bottom of screen,
188
- SPRITES .pop (i ) # remove fireball sprite
189
- PLAY_GROUP .pop (i + 1 )
187
+ if y >= macropad .display .height : # Off bottom of screen,
188
+ sprites .pop (i ) # remove fireball sprite
189
+ play_group .pop (i + 1 )
190
190
continue
191
- elif y >= MACROPAD .display .height - 40 :
192
- if COLUMN_PRESSED [column ]:
191
+ if y >= macropad .display .height - 40 :
192
+ if column_pressed [column ]:
193
193
# Fireball caught, ouch!
194
194
background_sound ('sizzle.wav' ) # I smell bacon
195
195
sprite .paused = True
196
- sprite .start_time = NOW
197
- tile .y = MACROPAD .display .height - 20
198
- LIFE_BAR .value = max (0 , LIFE_BAR .value - 5 )
196
+ sprite .start_time = now
197
+ tile .y = macropad .display .height - 20
198
+ life_bar .value = max (0 , life_bar .value - 5 )
199
199
for x in range (0 , 9 , 4 ):
200
- MACROPAD .pixels [x + sprite .column ] = (255 , 0 , 0 )
200
+ macropad .pixels [x + sprite .column ] = (255 , 0 , 0 )
201
201
else : # Is egg...
202
- if y >= MACROPAD .display .height - 22 :
202
+ if y >= macropad .display .height - 22 :
203
203
# Egg hit ground
204
204
background_sound ('splat.wav' )
205
205
sprite .paused = True
206
- sprite .start_time = NOW
207
- tile .y = MACROPAD .display .height - 22
206
+ sprite .start_time = now
207
+ tile .y = macropad .display .height - 22
208
208
tile [0 ] = 1 # Change sprite to broken egg
209
- LIFE_BAR .value = max (0 , LIFE_BAR .value - 5 )
210
- MACROPAD .pixels [8 + sprite .column ] = (255 , 255 , 0 )
211
- elif COLUMN_PRESSED [column ]:
212
- if y >= MACROPAD .display .height - 40 :
209
+ life_bar .value = max (0 , life_bar .value - 5 )
210
+ macropad .pixels [8 + sprite .column ] = (255 , 255 , 0 )
211
+ elif column_pressed [column ]:
212
+ if y >= macropad .display .height - 40 :
213
213
# Egg caught at right time
214
214
background_sound ('rawr.wav' )
215
215
sprite .paused = True
216
- sprite .start_time = NOW
217
- tile .y = MACROPAD .display .height - 22
216
+ sprite .start_time = now
217
+ tile .y = macropad .display .height - 22
218
218
tile [0 ] = 2 # Hatchling
219
- MACROPAD .pixels [4 + sprite .column ] = (0 , 255 , 0 )
220
- SCORE += 10
221
- PLAY_GROUP [- 1 ].text = str (SCORE )
222
- elif y >= MACROPAD .display .height - 58 :
219
+ macropad .pixels [4 + sprite .column ] = (0 , 255 , 0 )
220
+ score += 10
221
+ play_group [- 1 ].text = str (score )
222
+ elif y >= macropad .display .height - 58 :
223
223
# Egg caught too early
224
224
background_sound ('splat.wav' )
225
225
sprite .paused = True
226
- sprite .start_time = NOW
227
- tile .y = MACROPAD .display .height - 40
226
+ sprite .start_time = now
227
+ tile .y = macropad .display .height - 40
228
228
tile [0 ] = 1 # Broken egg
229
- LIFE_BAR .value = max (0 , LIFE_BAR .value - 5 )
230
- MACROPAD .pixels [sprite .column ] = (255 , 255 , 0 )
229
+ life_bar .value = max (0 , life_bar .value - 5 )
230
+ macropad .pixels [sprite .column ] = (255 , 255 , 0 )
231
231
232
232
# Select shadow bitmaps based on each column's lowest egg
233
233
for i in range (4 ):
234
- SHADOW [i ] = min (4 , int (COLUMN_MAX [i ] * SHADOW_SCALE ))
234
+ shadow [i ] = min (4 , int (column_max [i ] * shadow_scale ))
235
235
236
236
# Time to introduce a new sprite? 1/20 chance each frame, if space
237
- if (len (SPRITES ) < MAX_EGGS and random .random () < 0.05 and
238
- max (COLUMN_MIN ) > 16 ):
237
+ if (len (sprites ) < MAX_EGGS and random .random () < 0.05 and
238
+ max (column_min ) > 16 ):
239
239
# Pick a column randomly...if it's occupied, keep trying...
240
240
while True :
241
- COLUMN = random .randint (0 , 3 )
242
- if COLUMN_MIN [ COLUMN ] > 16 :
241
+ column = random .randint (0 , 3 )
242
+ if column_min [ column ] > 16 :
243
243
# Found a clear spot. Add sprite and break loop
244
- SPRITES .append (Sprite (COLUMN , NOW ))
245
- PLAY_GROUP .insert (- 2 , displayio .TileGrid (SPRITE_BITMAP ,
246
- pixel_shader = SPRITE_PALETTE ,
244
+ sprites .append (Sprite (column , now ))
245
+ play_group .insert (- 2 , displayio .TileGrid (sprite_bitmap ,
246
+ pixel_shader = sprite_palette ,
247
247
width = 1 , height = 1 ,
248
248
tile_width = 16 ,
249
- tile_height = SPRITE_BITMAP .height ,
250
- x = COLUMN * 16 ,
249
+ tile_height = sprite_bitmap .height ,
250
+ x = column * 16 ,
251
251
y = - 16 ))
252
252
break
253
253
254
- MACROPAD .display .refresh ()
255
- MACROPAD .pixels .show ()
256
- if not AUDIO .playing :
254
+ macropad .display .refresh ()
255
+ macropad .pixels .show ()
256
+ if not audio .playing :
257
257
# pylint: disable=protected-access
258
- MACROPAD ._speaker_enable .value = False
258
+ macropad ._speaker_enable .value = False
259
259
gc .collect ()
260
260
261
261
# Encoder button pauses/resumes game.
262
- MACROPAD .encoder_switch_debounced .update ()
263
- if MACROPAD .encoder_switch_debounced .pressed :
262
+ macropad .encoder_switch_debounced .update ()
263
+ if macropad .encoder_switch_debounced .pressed :
264
264
for n in (True , False , True ): # Press, release, press
265
- while n == MACROPAD .encoder_switch_debounced .pressed :
266
- MACROPAD .encoder_switch_debounced .update ()
265
+ while n == macropad .encoder_switch_debounced .pressed :
266
+ macropad .encoder_switch_debounced .update ()
267
267
# Sprite start times must be offset by pause duration
268
268
# because time.monotonic() is used for drop physics.
269
- NOW = time .monotonic () - NOW # Pause duration
270
- for sprite in SPRITES :
271
- sprite .start_time += NOW
269
+ now = time .monotonic () - now # Pause duration
270
+ for sprite in sprites :
271
+ sprite .start_time += now
272
272
273
273
# GAME OVER ------------------------
274
274
275
275
time .sleep (1.5 ) # Pause display for a moment
276
- MACROPAD .pixels .fill (0 )
277
- MACROPAD .pixels .show ()
276
+ macropad .pixels .fill (0 )
277
+ macropad .pixels .show ()
278
278
# pylint: disable=protected-access
279
- MACROPAD ._speaker_enable .value = False
280
- # Pop any sprites from PLAY_GROUP (other elements remain, and SPRITES []
279
+ macropad ._speaker_enable .value = False
280
+ # Pop any sprites from play_group (other elements remain, and sprites []
281
281
# list is cleared at start of next game).
282
- for _ in SPRITES :
283
- PLAY_GROUP .pop (1 )
284
- END_GROUP [- 1 ].text = str (SCORE )
285
- show_screen (END_GROUP )
282
+ for _ in sprites :
283
+ play_group .pop (1 )
284
+ end_group [- 1 ].text = str (score )
285
+ show_screen (end_group )
0 commit comments