import time import os import board import terminalio import displayio import digitalio import pwmio from adafruit_display_text import label from adafruit_st7735r import ST7735R import random BTN_A = digitalio.DigitalInOut(board.BTN_A) BTN_A.switch_to_input(pull=digitalio.Pull.UP) BTN_B = digitalio.DigitalInOut(board.BTN_B) BTN_B.switch_to_input(pull=digitalio.Pull.UP) BTN_X = digitalio.DigitalInOut(board.BTN_X) BTN_X.switch_to_input(pull=digitalio.Pull.UP) BTN_Y = digitalio.DigitalInOut(board.BTN_Y) BTN_Y.switch_to_input(pull=digitalio.Pull.UP) # Release any resources currently in use for the displays displayio.release_displays() spi = board.SPI() tft_cs = board.CS tft_dc = board.D1 display_bus = displayio.FourWire( spi, command=tft_dc, chip_select=tft_cs, reset=board.D0 ) display = ST7735R(display_bus, width=128, height=160, rotation=0, bgr=True, colstart=2, rowstart=1) # bl = digitalio.DigitalInOut(board.PWM0) # bl.direction = digitalio.Direction.OUTPUT # bl.value = True bl = pwmio.PWMOut(board.PWM0, frequency=5000, duty_cycle=0) bl.duty_cycle = 60000 # Make the display context group = displayio.Group() display.show(group) ui_group = displayio.Group(scale=1, x=100, y=0) color_bitmap = displayio.Bitmap(28, 160, 1) color_palette = displayio.Palette(1) color_palette[0] = 0x444444 bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0) ui_group.append(bg_sprite) text_group = displayio.Group(scale=1, x=0, y=5) text = "Score" text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF) text_group.append(text_area) ui_group.append(text_group) text_group = displayio.Group(scale=1, x=0, y=15) text = "0" text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF) text_group.append(text_area) ui_group.append(text_group) group.append(ui_group) def make_row(): return [{'value': False, 'color': None} for _ in range(10)] def make_grid(): return [make_row() for _ in range(16)] spawn_pos = 4 bricks = [ {'color': 0xFF0000, 'grid': [ [True], [True, True, True]]}, {'color': 0x5555BB, 'grid': [ [True], [True], [True], [True]]}, {'color': 0xFFCC00, 'grid': [ [False, True], [True, True, True]]}, {'color': 0x22FF22, 'grid': [ [True, True], [False, True, True]]}, {'color': 0xFC7005, 'grid': [ [False, False, True], [True, True, True]]}, {'color': 0x0077AA, 'grid': [ [False, True, True], [True, True]]}, {'color': 0xFF00FF, 'grid': [ [True, True], [True, True]]}] score = 0 move_grid = make_grid() game_grid = make_grid() game_speed_delay = 0.5 game_speed_increase = 0.01 move_speed_delay = 0.15 move_group = displayio.Group(scale=1, x=0, y=0) game_group = displayio.Group(scale=1, x=0, y=0) group.append(move_group) group.append(game_group) def update_grid(grid, index, group_to_append_to): # TODO Don't redraw everything group_to_append_to = displayio.Group(scale=1, x=0, y=0) for i, row in enumerate(grid): for j, cell in enumerate(row): if cell['value']: color_bitmap = displayio.Bitmap(10, 10, 1) color_palette = displayio.Palette(1) color_palette[0] = cell['color'] bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=j * 10, y=i*10) group_to_append_to.append(bg_sprite) group.pop(index) group.insert(index, group_to_append_to) def update_grids(): update_grid(move_grid, 1, move_group) update_grid(game_grid, 2, game_group) def spawn_brick(): brick_data = bricks[random.randint(0 , len(bricks) - 1)] for i, row in enumerate(brick_data['grid']): for j, cell in enumerate(row): if cell: move_grid_cell = move_grid[i][spawn_pos + j] move_grid_cell['value'] = True move_grid_cell['color'] = brick_data['color'] def shift_grid(move_grid, direction, disallowed): new_grid = make_grid() ok = True for i, row in enumerate(move_grid): if not ok: break for k, cell in enumerate(row): if cell['value']: if k == disallowed or game_grid[i][k + direction]['value']: ok = False break new_grid[i][k + direction] = cell if ok: return new_grid spawn_brick() update_grids() loop_end_time = time.monotonic() + game_speed_delay next_move_end_time = 0 while True: # TODO Button interupts if not BTN_A.value and next_move_end_time < time.monotonic(): # Pause next_move_end_time = time.monotonic() + move_speed_delay paused_text_index = len(group) text_group = displayio.Group(scale=1, x=40, y=80) text = "Paused" text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF) text_group.append(text_area) # Subgroup for text scaling group.append(text_group) while BTN_A.value == False: pass #print('Waiting for button to be pressed') while BTN_A.value == True: pass #print('Unpause') group.pop(paused_text_index) #print('Waiting for button to be relased') while BTN_A.value == False: pass #print('Button relased') elif BTN_B.value == False: # Rotate brick if next_move_end_time < time.monotonic(): next_move_end_time = time.monotonic() + move_speed_delay new_grid = make_grid() offset_x = None offset_y = None for x, row in enumerate(move_grid): for y, cell in enumerate(row): if cell['value']: if offset_x is None: offset_x = x offset_y = y new_grid[y][x] = cell move_grid = new_grid update_grid(move_grid, 1, move_group) #print('Waiting for button to be relased') while BTN_B.value == False: pass elif BTN_X.value == False: # Move brick left if next_move_end_time < time.monotonic(): next_move_end_time = time.monotonic() + move_speed_delay new_grid = shift_grid(move_grid, -1, 0) if new_grid is not None: move_grid = new_grid update_grid(move_grid, 1, move_group) elif BTN_Y.value == False: # Move brick right if next_move_end_time < time.monotonic(): next_move_end_time = time.monotonic() + move_speed_delay new_grid = shift_grid(move_grid, +1, 9) if new_grid is not None: move_grid = new_grid update_grid(move_grid, 1, move_group) if loop_end_time < time.monotonic(): #print('loop') loop_end_time = time.monotonic() + game_speed_delay move_grid.pop(15) move_grid.insert(0, make_row()) hit_something = False for i, row in enumerate(move_grid): if hit_something: break for j, cell in enumerate(row): if cell['value']: if i == 15 or game_grid[i+1][j]['value']: #print('Hit') hit_something = True if i < 2: game_over_text_index = len(group) text_group = displayio.Group(scale=1, x=40, y=80) text = "Game over" text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF) text_group.append(text_area) # Subgroup for text scaling group.append(text_group) time.sleep(2) group[0][2][0].text = '0' group.pop(game_over_text_index) game_grid = make_grid() move_grid = make_grid() spawn_brick() update_grids() break for h, row_a in enumerate(move_grid): for k, cell_a in enumerate(row_a): if cell_a['value']: game_grid[h][k] = cell_a move_grid = make_grid() full_rows = [] for l, row_b in enumerate(game_grid): full_row = True for m, cell_b in enumerate(row_b): if not cell_b['value']: full_row = False break if full_row: full_rows.append(l) game_speed_delay -= game_speed_increase if len(full_rows) != 0: for line in full_rows: game_grid.pop(line) game_grid.insert(0, make_row()) group[0][2][0].text = str(int(group[0][2][0].text) + (5 * len(full_rows))) spawn_brick() break update_grids()