CIRCUITPYcode.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory PyBadge_Blinka_Jump_Game/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.
CIRCUITPY

# SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries # # SPDX-License-Identifier: MIT import time from random import randint from micropython import const import board import terminalio import displayio import adafruit_imageload import digitalio import simpleio from keypad import ShiftRegisterKeys, Event from adafruit_display_text import label # setup for PyBadge buttons BUTTON_LEFT = const(7) BUTTON_UP = const(6) BUTTON_DOWN = const(5) BUTTON_RIGHT = const(4) BUTTON_SEL = const(3) BUTTON_START = const(2) BUTTON_A = const(1) BUTTON_B = const(0) pad = ShiftRegisterKeys(clock=board.BUTTON_CLOCK, data=board.BUTTON_OUT, latch=board.BUTTON_LATCH, key_count=8, value_when_pressed=True, max_events=1) latest_event = Event(key_number=8) last_read = 0 # enables speaker speakerEnable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speakerEnable.switch_to_output(value=True) # Sprite cell values EMPTY = 0 BLINKA_1 = 1 BLINKA_2 = 2 SPARKY = 3 HEART = 4 JUMP_1 = 5 JUMP_2 = 6 # creates display display = board.DISPLAY # scale=2 allows the sprites to be bigger group = displayio.Group(scale=2) # Blinka sprite setup blinka, blinka_pal = adafruit_imageload.load("/spritesNew.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) # creates a transparent background for Blinka blinka_pal.make_transparent(7) blinka_grid = displayio.TileGrid(blinka, pixel_shader=blinka_pal, width=2, height=1, tile_height=16, tile_width=16, default_tile=EMPTY) blinka_grid.x = 0 blinka_grid.y = 32 blinka_group = displayio.Group() blinka_group.append(blinka_grid) # first Sparky sprite sparky0, sparky0_pal = adafruit_imageload.load("/spritesNew.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) sparky0_pal.make_transparent(7) sparky0_grid = displayio.TileGrid(sparky0, pixel_shader=sparky0_pal, width=1, height=1, tile_height=16, tile_width=16, default_tile=SPARKY) # all Sparky sprites begin off screen sparky0_grid.x = 100 sparky0_grid.y = 32 sparky0_group = displayio.Group() sparky0_group.append(sparky0_grid) # 2nd Sparky sprite sparky1, sparky1_pal = adafruit_imageload.load("/spritesNew.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) sparky1_pal.make_transparent(7) sparky1_grid = displayio.TileGrid(sparky1, pixel_shader=sparky1_pal, width=1, height=1, tile_height=16, tile_width=16, default_tile=SPARKY) sparky1_grid.x = 100 sparky1_grid.y = 32 sparky1_group = displayio.Group() sparky1_group.append(sparky1_grid) # 3rd Sparky sprite sparky2, sparky2_pal = adafruit_imageload.load("/spritesNew.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) sparky2_pal.make_transparent(7) sparky2_grid = displayio.TileGrid(sparky2, pixel_shader=sparky2_pal, width=1, height=1, tile_height=16, tile_width=16, default_tile=SPARKY) sparky2_grid.x = 100 sparky2_grid.y = 32 sparky2_group = displayio.Group() sparky2_group.append(sparky2_grid) # heart sprite group life_bit, life_pal = adafruit_imageload.load("/spritesNew.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) life_grid = displayio.TileGrid(life_bit, pixel_shader=life_pal, width=3, height=1, tile_height=16, tile_width=16, default_tile=HEART) life_group = displayio.Group() life_group.append(life_grid) # adding all graphics groups to the main display group group.append(blinka_group) group.append(sparky0_group) group.append(sparky1_group) group.append(sparky2_group) group.append(life_group) # text area for the running score score_text = " " font = terminalio.FONT score_color = 0x0000FF # text for "game over" graphic game_over_text = label.Label(font, text = " ", color = 0xFF00FF) # score text score_area = label.Label(font, text=score_text, color=score_color) # text for "new game" graphic new_game_text = label.Label(font, text = " ", color = 0xFF00FF) # coordinants for text areas score_area.x = 57 score_area.y = 6 game_over_text.x = 13 game_over_text.y = 30 new_game_text.x = 8 new_game_text.y = 30 # creating a text display group text_group = displayio.Group() text_group.append(score_area) text_group.append(game_over_text) text_group.append(new_game_text) # adding text group to main display group group.append(text_group) # displaying main display group display.root_group = group # state for hit detection crash = False # states to see if a Sparky is on screen sparky0 = False sparky1 = False sparky2 = False # array of Sparky states sparky_states = [sparky0, sparky1, sparky2] # array of x location for Sparky's sparky_x = [sparky0_grid.x, sparky1_grid.x, sparky2_grid.x] # function to display the heart sprites for lives def life(): for _ in range(0, 3): life_grid[_, 0] = EMPTY for hearts in range(life_count): life_grid[hearts, 0] = HEART # lives at beginning of the game life_count = 3 # variables for scoring jump_score = 0 total_score = 0 bonus = 0 # state for Blinka being in default 'slither' mode snake = True # state to check if Blinka has jumped over Sparky cleared = False # state for the end of a game end = False # state for a new game beginning new_game = True # state for detecting game over game_over = False # variable to change between Blinka's two slither sprites b = 1 # variable to hold time.monotonic() count for Blinka slither animation slither = 0 # variables to hold time.monotonic() count to delay Sparky spawning blue = 0 smoke = 0 monster = 0 # jump button press state jump_pressed = False while True: # checks if button has been pressed if (last_read + 0.01) < time.monotonic(): pad.events.get_into(latest_event) last_read = time.monotonic() # new game if new_game and not game_over: # graphics for new game splash screen blinka_grid.y = 16 blinka_grid[0] = JUMP_1 blinka_grid[1] = JUMP_2 sparky0_grid.x = 5 sparky1_grid.x = 40 sparky2_grid.x = 65 score_area.text = str(300) new_game_text.text = "BLINKA JUMP" life() # if start is pressed... if latest_event: if latest_event.key_number == BUTTON_START: # prepares display for gameplay print("start game") new_game_text.text = " " life_count = 3 start = time.monotonic() new_game = False end = False sparky0_grid.x = 100 sparky1_grid.x = 100 sparky2_grid.x = 100 # if game has started... if not game_over and not new_game: # gets time.monotonic() to have a running score mono = time.monotonic() score = mono - start # adds 10 points every time a Sparky is cleared total_score = score + jump_score # displays score as text score_area.text = str(int(total_score)) # puts Sparky states and x location into callable arrays for s in range(3): sparky_state = sparky_states[s] sparky_location = sparky_x[s] # Sparkys are generated using a staggered delay # and matching an int to a random int # 1st Sparky if (blue + 0.03) < time.monotonic(): if randint(1, 15) == 3: sparky_states[0] = True blue = time.monotonic() # 2nd Sparky if (smoke + 0.07) < time.monotonic(): if randint(1, 15) == 7: sparky_states[1] = True smoke = time.monotonic() # 3rd Sparky if (monster + 0.12) < time.monotonic(): if randint(1, 15) == 12: sparky_states[2] = True monster = time.monotonic() # if a Sparky is generated, it scrolls across the screen 1 pixel at a time # 1st Sparky if sparky_states[0] is True: sparky0_grid.x -= 1 sparky_x[0] = sparky0_grid.x display.refresh(target_frames_per_second=120) # when a Sparky is 16 pixels off the display, # it goes back to its starting position if sparky0_grid.x is -16: sparky_states[0] = False sparky0_grid.x = 100 sparky_x[0] = sparky0_grid.x # 2nd Sparky if sparky_states[1] is True: sparky1_grid.x -= 1 sparky_x[1] = sparky1_grid.x display.refresh(target_frames_per_second=120) if sparky1_grid.x is -16: sparky_states[1] = False sparky1_grid.x = 100 sparky_x[1] = sparky1_grid.x # 3rd Sparky if sparky_states[2] is True: sparky2_grid.x -= 1 sparky_x[2] = sparky2_grid.x display.refresh(target_frames_per_second=120) if sparky2_grid.x is -16: sparky_states[2] = False sparky2_grid.x = 100 sparky_x[2] = sparky2_grid.x # if no lives are left then the game ends if life_count is 0: game_over = True # if the A button is pressed then Blinka is no longer in the default # slither animation aka she jumps if latest_event.key_number == BUTTON_A: if latest_event.pressed: jump_pressed = True snake = False else: jump_pressed = False snake = True # heart sprites are displayed to show life count life() # if Blinka is slithering... if snake: # Blinka default location blinka_grid.y = 32 # empty 2nd tile so that the jump sprite can be shown using # the same tilegrid blinka_grid[1] = EMPTY # every .15 seconds Blinka's slither sprite changes # so that her slithering is animated # b holds tilegrid position to display correct sprite if (slither + 0.15) < time.monotonic(): blinka_grid[0] = b b += 1 slither = time.monotonic() if b > 2: b = 1 # if a Sparky collides with Blinka while she is slithering... for s in range(3): if sparky_x[s] == 8 and blinka_grid.y == 32: # tone is played simpleio.tone(board.SPEAKER, 493.88, 0.05) simpleio.tone(board.SPEAKER, 349.23, 0.05) # lose a life life_count = life_count - 1 # if the A button is pressed then... else: # Blinka JUMPS # y location changes one row up and both jump sprites are shown blinka_grid.y = 16 blinka_grid[0] = JUMP_1 blinka_grid[1] = JUMP_2 # if Blinka jumps over a Sparky... for j in range(3): if sparky_x[j] == 8 and not cleared: # 10 points to the player bonus += 1 jump_score = bonus * 10 cleared = True # special victory tone is played simpleio.tone(board.SPEAKER, 523.25, 0.005) simpleio.tone(board.SPEAKER, 783.99, 0.005) if not jump_pressed: # resets back to Blinka animation snake = True # resets that Blinka has not jumped over a Sparky cleared = False # if there are no more lives, the game is over if game_over and not new_game: # game over text is displayed game_over_text.text = "GAME OVER" score_area.text = " " # end game tone is played # and then the screen holds with the last # sprites on screen and game over text if not end: simpleio.tone(board.SPEAKER, 220, 0.05) simpleio.tone(board.SPEAKER, 207.65, 0.05) simpleio.tone(board.SPEAKER, 196, 0.5) end = True # if the start button is pressed... if latest_event and game_over: if latest_event.key_number == BUTTON_START: # display, states and score are reset for gameplay game_over_text.text = " " life_count = 3 start = time.monotonic() game_over = False end = False total_score = 0 jump_score = 0 bonus = 0 score = 0 blue = 0 smoke = 0 monster = 0 sparky0_grid.x = 100 sparky1_grid.x = 100 sparky2_grid.x = 100 # game begins again with all Sparky's off screen
Page last edited January 22, 2025
Text editor powered by tinymce.