/ RGB_Matrix_Dreidel_Game / code.py
code.py
1 # SPDX-FileCopyrightText: 2021 Liz Clark for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 import time 6 import random 7 import board 8 import pwmio 9 import displayio 10 import adafruit_imageload 11 from audiocore import WaveFile 12 from audioio import AudioOut 13 from adafruit_motor import servo 14 from digitalio import DigitalInOut, Direction, Pull 15 from adafruit_matrixportal.matrix import Matrix 16 17 # setup for down button on matrixportal 18 switch = DigitalInOut(board.BUTTON_DOWN) 19 switch.direction = Direction.INPUT 20 switch.pull = Pull.UP 21 22 # setup for break beam sensor 23 break_beam = DigitalInOut(board.A1) 24 break_beam.direction = Direction.INPUT 25 break_beam.pull = Pull.UP 26 27 # pwm for servo 28 servo_pwm = pwmio.PWMOut(board.A4, duty_cycle=2 ** 15, frequency=50) 29 30 # servo setup 31 servo = servo.Servo(servo_pwm) 32 servo.angle = 90 33 34 # import dreidel song audio file 35 wave_file = open("dreidel_song.wav", "rb") 36 wave = WaveFile(wave_file) 37 38 # setup for audio out 39 audio = AudioOut(board.A0) 40 41 # setup for matrix display 42 matrix = Matrix(width=32, height=32) 43 display = matrix.display 44 45 group = displayio.Group() 46 47 # import dreidel bitmap 48 dreidel_bit, dreidel_pal = adafruit_imageload.load("/dreidel.bmp", 49 bitmap=displayio.Bitmap, 50 palette=displayio.Palette) 51 52 dreidel_grid = displayio.TileGrid(dreidel_bit, pixel_shader=dreidel_pal, 53 width=1, height=1, 54 tile_height=32, tile_width=32, 55 default_tile=0, 56 x=0, y=0) 57 58 group.append(dreidel_grid) 59 60 # show dreidel bitmap 61 display.show(group) 62 63 timer = 0 # time.monotonic() holder 64 spin = 0 # index for tilegrid 65 speed = 0.1 # rate that bitmap updates 66 clock = 0 # initial time.monotonic() holder to act as time keeper 67 gimel = 3 # bitmap index for gimel, the winning character 68 countdown = 5 # countdown for length of game. default is 5 seconds 69 beam_state = False # state machine for break beam 70 reset = False # state for reset of game 71 dreidel = False # state to track if dreidel game is running 72 73 clock = time.monotonic() # initial time.monotonic() 74 75 while True: 76 # debouncing for break beam sensor 77 if not break_beam.value and not beam_state: 78 beam_state = True 79 80 # if the break beam sensor is triggered or the down button is pressed... 81 if (not break_beam.value and beam_state) or not switch.value: 82 # update break beam state 83 beam_state = False 84 # begin reset for game states 85 reset = True 86 print("pressed") 87 # quick delay 88 time.sleep(0.1) 89 90 # if reset state... 91 if reset: 92 # hold time.monotonic() value 93 clock = time.monotonic() 94 # reset countdown 95 countdown = 5 96 # choose random side of dreidel to begin spinning on 97 spin = random.randint(0, 3) 98 # choose random speed spin the dreidel 99 speed = random.uniform(0.05, 0.1) 100 # set game state to True 101 dreidel = True 102 # turn off reset state 103 reset = False 104 105 # if the game is running... 106 if dreidel: 107 # play the dreidel song 108 audio.play(wave) 109 110 # while the dreidel song is playing... 111 while audio.playing: 112 # if more time has passed than the random delay setup in reset... 113 if (timer + speed) < time.monotonic(): 114 # dreidel grid index is set to spin value 115 dreidel_grid[0] = spin 116 # spin is increased by 1 117 spin += 1 118 # timer is updated to current time 119 timer = time.monotonic() 120 121 # if a second has passed... 122 if time.monotonic() > (clock + 1): 123 print(clock) 124 print(spin) 125 # the delay is increased to slow down the dreidel 126 speed += 0.05 127 # clock is set to current time 128 clock = time.monotonic() 129 # countdown value is decreased by 1 130 countdown -= 1 131 132 # if countdown is 0 aka 5 seconds has passed since the start of game... 133 if countdown == 0: 134 # if the bitmap is showing gimel... 135 # you win! 136 if spin is gimel: 137 # the servo turns 90 degrees to dump out chocolate coins 138 servo.angle = 0 139 # 2 second delay 140 time.sleep(2) 141 # servo turns back to default position 142 for i in range(0, 90, 2): 143 servo.angle = i 144 time.sleep(0.1) 145 # ensures servo is in default position 146 servo.angle = 90 147 # stop playing the dreidel song 148 audio.stop() 149 # game state is turned off 150 dreidel = False 151 152 # if you didn't win... 153 else: 154 # the dreidel song stops 155 audio.stop() 156 # game state is turned off 157 dreidel = False 158 159 # if you are at the end of the sprite sheet... 160 if spin > 3: 161 # index is reset to 0 162 spin = 0