The code begins by importing the CircuitPython libraries.
import time import board import audioio import audiomp3 import framebufferio import rgbmatrix import displayio import adafruit_imageload import digitalio from adafruit_display_shapes.rect import Rect from adafruit_bitmap_font import bitmap_font from adafruit_display_text import label
The RGB matrix is setup using the rgbmatrix library.
# matrix setup displayio.release_displays() matrix = rgbmatrix.RGBMatrix( width=64, height=32, bit_depth=4, rgb_pins=[board.D6, board.D5, board.D9, board.D11, board.D10, board.D12], addr_pins=[board.A5, board.A4, board.A3, board.A2], clock_pin=board.D13, latch_pin=board.D0, output_enable_pin=board.D1, ) display = framebufferio.FramebufferDisplay(matrix)
Then, the two display groups are created. There will be a group to show the start-up graphic and a second one to display the score when you're playing the game.
# display groups start_group = displayio.Group(scale=1) score_group = displayio.Group(scale=1)
The text (score_text
) and colorful background (score_bg
) are setup next for the scoreboard. The text is using a bitmap font.
# text & bg color setup for scoreboard score_text = " " font = bitmap_font.load_font("/Fixedsys-32.bdf") yellow = (255, 127, 0) pink = 0xFF00FF score_text = label.Label(font, text=score_text, color=0x0) score_text.x = 23 score_text.y = 15 score_bg = Rect(0, 0, 64, 32, fill=yellow, outline=pink, stroke=3)
Following the score text setup, the start-up graphic bitmap is setup using the adafruit_imageload library.
# start splash screen graphic start, start_pal = adafruit_imageload.load("/pixelHoops.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) start_grid = displayio.TileGrid(start, pixel_shader=start_pal, width=64, height=32)
The start-up bitmap and score text graphics are added to their respective display groups. The start-up bitmap is shown first using display.root_group = start_group
.
# adding graphics to display groups start_group.append(start_grid) score_group.append(score_bg) score_group.append(score_text) # start by showing start splash display.root_group = start_group
After the display is setup, the I/O pins are setup for the break beam LED, push button and speaker. The LED and button are setup as inputs and the speaker is setup as an AudioOut
using the audioio library.
# setup for break beam LED pin break_beam = digitalio.DigitalInOut(board.A1) break_beam.direction = digitalio.Direction.INPUT break_beam.pull = digitalio.Pull.UP # setup for button pin button = digitalio.DigitalInOut(board.D4) button.direction = digitalio.Direction.INPUT button.pull = digitalio.Pull.UP # setup for speaker pin speaker = audioio.AudioOut(board.A0)
The MP3Decoder
is setup before the loop, similar to how display objects are setup early in the code. This helps to save memory when playing multiple .mp3 files. Notice how you aren't playing an .mp3 in this section, it's purely for setup.
# mp3 decoder setup file = "/hoopBloop0.mp3" mp3stream = audiomp3.MP3Decoder(open(file, "rb"))
The final portion of the setup creates that state machines that will be used in the loop. Their functions are commented below.
# state machines used in the loop score = 0 # holds your score for the game hoops = False # tracks if a game is active or not button_state = False # button debouncing beam_state = False # break beam LED debouncing sample = 0 # file count for the mp3 files
The loop begins with debouncing setup for the button and break beam LED. This eliminates any glitches in receiving data from their inputs.
while True: # button debouncing if not button.value and not button_state: button_state = True # debouncing for break beam LED if not break_beam.value and not beam_state: beam_state = True
The button has a different function depending on whether or not a game is in progress. If a game has not started, then pressing the button begins a new game and also changes the display to show the scoreboard graphic.
# if a game hasn't started and you press the button: if not button.value and not hoops: # game starts hoops = True button_state = False # display shows scoreboard display.root_group = score_group print("start game!") time.sleep(0.5)
A game runs if the hoops
state is True
. Every time the break beam LED detects a break, your score increases by two points and an .mp3 file plays.
There are three different .mp3 files and they play in order as the game goes on. The code is able to iterate through the files easily because they are all named hoopBloop*. By naming them like this, you can use "/hoopBloop{}.mp3".format(sample)
, to iterate through them with sample
holding the number.
The code is referencing the earlier mp3stream
that was setup before the loop to decode and play the .mp3 files.
Additionally, there is some text formatting that takes place depending on how many digits your score is. This allows for the score to remain centered during game play.
if hoops: # if the break beam LED detects a hoop: if not break_beam.value and beam_state: # score increase by 2 points score += 2 # an mp3 plays file = "/hoopBloop{}.mp3".format(sample) mp3stream.file = open(file, "rb") speaker.play(mp3stream) print("score!") # resets break beam beam_state = False # increases mp3 file count # plays the 3 files in order sample = (sample + 1) % 3 # score text x pos if 4 digit score if score >= 1000: score_text.x = -1 # score text x pos if 3 digit score elif score >= 100: score_text.x = 7 # score text x pos if 2 digit score elif score >= 10: score_text.x = 16 # score text x pos if 1 digit score elif score >= 0: score_text.x = 23 # updates score text to show current score score_text.text = score time.sleep(0.1)
If a game is in progress and you press the button, it changes the hoops
state to False
and ends the game. The score is also reset to 0
and the display shows the start-up bitmap.
# if a game is in progress and you press the button: if not button.value and hoops: # game stops hoops = False button_state = False # score is reset to 0 score = 0 # display shows the start splash graphic display.root_group = start_group print("end game!") time.sleep(0.5)
Text editor powered by tinymce.