[refactor] Cleanup code
- Rename joystick library to helpers - Put color565 function in helpers.py - Switch screen width and height names as game runs in landscrape - Enumerate levels for readability - Update docstrings - Rework splash screen to use binary operators - Extract create bricks and create lives functions - Reowrk main game loop logic to support next level
This commit is contained in:
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
# Program Documentation
|
# Program Documentation
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
This program is a simple game implemented in MicroPython for the Raspberry Pi Pico with a Pico-LCD-1.14 display. The game involves controlling a character to avoid obstacles and score points. The program includes a splash screen, game over screen, and a main game loop.
|
This program is a simple game implemented in MicroPython for the Raspberry Pi Pico with a Pico-LCD-1.14 display. The game involves controlling a paddle to acontrol a ball to break a brick wall and score points. The program includes a splash screen, game over screen, and a main game loop.
|
||||||
|
|
||||||
## Framebuffer
|
## Framebuffer
|
||||||
The program use framebuffer to draw the game graphics. The framebuffer is a 2D array that represents the pixels on the display. The program uses the `framebuf` module to create and manipulate the framebuffer. The framebuffer is then copied to the display using the `blit` method.
|
The program uses a framebuffer to draw the game graphics. The framebuffer is a 2D array that represents the pixels on the display. The program uses the micropyhton `framebuf` module to create and manipulate the framebuffer. The framebuffer is then copied to the display using the `blit` method.
|
||||||
|
|
||||||
## Multithreading
|
## Multithreading
|
||||||
|
|
||||||
|
|||||||
+118
-79
@@ -1,10 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
Threaded bouncing boxes with frame buffer
|
Threaded breakout game with frame buffer
|
||||||
|
|
||||||
Uses a single shot function for second core SPI handler.
|
Uses a single shot function for second core SPI handler.
|
||||||
This cleans itself when the function exits removing the
|
This cleans itself when the function exits removing the
|
||||||
need for a garbage collection call.
|
need for a garbage collection call.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from gc import collect
|
from gc import collect
|
||||||
collect()
|
collect()
|
||||||
@@ -18,15 +17,11 @@ from random import random, seed, randint
|
|||||||
from utime import sleep_us, ticks_cpu, ticks_us
|
from utime import sleep_us, ticks_cpu, ticks_us
|
||||||
import _thread
|
import _thread
|
||||||
import st7789 as st7789
|
import st7789 as st7789
|
||||||
from joystick import Joystick
|
from helpers import Joystick, color565
|
||||||
|
|
||||||
# ============================
|
# ============================
|
||||||
# Helper Functions
|
# Helper Functions
|
||||||
# ============================
|
# ============================
|
||||||
def color565(r, g, b):
|
|
||||||
"""Convert RGB888 to RGB565."""
|
|
||||||
return (((g & 0b00011100) << 3) + ((r & 0b11111000) >> 3) << 8) + (b & 0b11111000) + ((g & 0b11100000) >> 5)
|
|
||||||
|
|
||||||
|
|
||||||
RED = color565(0, 0, 255)
|
RED = color565(0, 0, 255)
|
||||||
GREEN = color565(0, 255, 0)
|
GREEN = color565(0, 255, 0)
|
||||||
@@ -45,9 +40,9 @@ def clear_display():
|
|||||||
# ============================
|
# ============================
|
||||||
# Constants and Configuration
|
# Constants and Configuration
|
||||||
# ============================
|
# ============================
|
||||||
SCREEN_WIDTH = 135
|
SCREEN_HEIGHT = 135
|
||||||
SCREEN_HEIGHT = 240
|
SCREEN_WIDTH = 240
|
||||||
SCREEN_ROTATION = 1
|
SCREEN_ROTATION = 1 # Landscape mode
|
||||||
|
|
||||||
PADDLE_WIDTH = 70
|
PADDLE_WIDTH = 70
|
||||||
PADDLE_HEIGHT = 10
|
PADDLE_HEIGHT = 10
|
||||||
@@ -66,6 +61,14 @@ SPLASH_WIDTH = 8
|
|||||||
SPLASH_HEIGHT = 5
|
SPLASH_HEIGHT = 5
|
||||||
SPLASH_PADDING = 2
|
SPLASH_PADDING = 2
|
||||||
|
|
||||||
|
# Game states
|
||||||
|
START_SCREEN = 0
|
||||||
|
PLAYING = 1
|
||||||
|
GAME_OVER = 2
|
||||||
|
GAME_WIN = 3
|
||||||
|
GAME_NEXT_LEVEL = 4
|
||||||
|
|
||||||
|
DEBOUNCE = 300_000
|
||||||
|
|
||||||
# ============================
|
# ============================
|
||||||
# set up SPI and display
|
# set up SPI and display
|
||||||
@@ -80,8 +83,8 @@ spi = SPI(1,
|
|||||||
|
|
||||||
display = st7789.ST7789(
|
display = st7789.ST7789(
|
||||||
spi,
|
spi,
|
||||||
SCREEN_WIDTH,
|
|
||||||
SCREEN_HEIGHT,
|
SCREEN_HEIGHT,
|
||||||
|
SCREEN_WIDTH,
|
||||||
reset=Pin(12, Pin.OUT),
|
reset=Pin(12, Pin.OUT),
|
||||||
cs=Pin(9, Pin.OUT),
|
cs=Pin(9, Pin.OUT),
|
||||||
dc=Pin(8, Pin.OUT),
|
dc=Pin(8, Pin.OUT),
|
||||||
@@ -90,9 +93,8 @@ display = st7789.ST7789(
|
|||||||
|
|
||||||
|
|
||||||
# FrameBuffer needs 2 bytes for every RGB565 pixel
|
# FrameBuffer needs 2 bytes for every RGB565 pixel
|
||||||
buffer_width = SCREEN_HEIGHT
|
buffer_width = SCREEN_WIDTH
|
||||||
buffer_height = SCREEN_WIDTH + 1
|
buffer_height = SCREEN_HEIGHT + 1
|
||||||
buffer_height = 136
|
|
||||||
buffer = bytearray(buffer_width * buffer_height * 2)
|
buffer = bytearray(buffer_width * buffer_height * 2)
|
||||||
fbuf = framebuf.FrameBuffer(buffer, buffer_width, buffer_height, framebuf.RGB565)
|
fbuf = framebuf.FrameBuffer(buffer, buffer_width, buffer_height, framebuf.RGB565)
|
||||||
|
|
||||||
@@ -104,8 +106,8 @@ render_frame = False
|
|||||||
|
|
||||||
class Paddle:
|
class Paddle:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.x = (SCREEN_HEIGHT - PADDLE_WIDTH) // 2
|
self.x = (SCREEN_WIDTH - PADDLE_WIDTH) // 2
|
||||||
self.y = SCREEN_WIDTH - PADDLE_HEIGHT - 5
|
self.y = SCREEN_HEIGHT - PADDLE_HEIGHT - 5
|
||||||
self.width = PADDLE_WIDTH
|
self.width = PADDLE_WIDTH
|
||||||
self.height = PADDLE_HEIGHT
|
self.height = PADDLE_HEIGHT
|
||||||
self.speed = PADDLE_SPEED
|
self.speed = PADDLE_SPEED
|
||||||
@@ -118,8 +120,8 @@ class Paddle:
|
|||||||
self.x += self.speed * direction
|
self.x += self.speed * direction
|
||||||
if self.x < 0:
|
if self.x < 0:
|
||||||
self.x = 0
|
self.x = 0
|
||||||
elif self.x > SCREEN_HEIGHT - self.width:
|
elif self.x > SCREEN_WIDTH - self.width:
|
||||||
self.x = SCREEN_HEIGHT - self.width
|
self.x = SCREEN_WIDTH - self.width
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
"""Draw paddle."""
|
"""Draw paddle."""
|
||||||
@@ -171,8 +173,8 @@ class Ball:
|
|||||||
"""Reset ball position to the center of the paddle.
|
"""Reset ball position to the center of the paddle.
|
||||||
Args: Paddle: The paddle object to position the ball on.
|
Args: Paddle: The paddle object to position the ball on.
|
||||||
"""
|
"""
|
||||||
self.x = SCREEN_HEIGHT // 2
|
self.x = SCREEN_WIDTH // 2
|
||||||
self.y = SCREEN_WIDTH // 2 - self.radius - 2
|
self.y = SCREEN_HEIGHT // 2 - self.radius - 2
|
||||||
self.x_speed = BALL_SPEED
|
self.x_speed = BALL_SPEED
|
||||||
self.y_speed = -BALL_SPEED
|
self.y_speed = -BALL_SPEED
|
||||||
|
|
||||||
@@ -185,8 +187,8 @@ class Ball:
|
|||||||
if self.x < 0:
|
if self.x < 0:
|
||||||
self.x = 0
|
self.x = 0
|
||||||
self.x_speed = -self.x_speed
|
self.x_speed = -self.x_speed
|
||||||
elif self.x > SCREEN_HEIGHT:
|
elif self.x > SCREEN_WIDTH:
|
||||||
self.x = SCREEN_HEIGHT - self.radius
|
self.x = SCREEN_WIDTH - self.radius
|
||||||
self.x_speed = -self.x_speed
|
self.x_speed = -self.x_speed
|
||||||
|
|
||||||
# Bounce off top screen edge
|
# Bounce off top screen edge
|
||||||
@@ -195,8 +197,8 @@ class Ball:
|
|||||||
self.y_speed = -self.y_speed
|
self.y_speed = -self.y_speed
|
||||||
|
|
||||||
# Drop through bottom screen edge & return True to indicate we lose a life
|
# Drop through bottom screen edge & return True to indicate we lose a life
|
||||||
if self.y > SCREEN_WIDTH:
|
if self.y > SCREEN_HEIGHT:
|
||||||
self.y = SCREEN_WIDTH
|
self.y = SCREEN_HEIGHT
|
||||||
self.y_speed = -self.y_speed
|
self.y_speed = -self.y_speed
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -214,7 +216,8 @@ class Brick:
|
|||||||
y (int): y-coordinate of the brick.
|
y (int): y-coordinate of the brick.
|
||||||
width (int): width of the brick.
|
width (int): width of the brick.
|
||||||
height (int): height of the brick.
|
height (int): height of the brick.
|
||||||
color (int): color of the brick."""
|
color (int): color of the brick.
|
||||||
|
"""
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.width = width
|
self.width = width
|
||||||
@@ -247,6 +250,7 @@ class BrickRow:
|
|||||||
self.brick_y = [offset_top] * BRICKS_PER_ROW
|
self.brick_y = [offset_top] * BRICKS_PER_ROW
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
"""Draw all bricks in the row."""
|
||||||
global fbuf
|
global fbuf
|
||||||
for brick in self.bricks:
|
for brick in self.bricks:
|
||||||
if brick is not None:
|
if brick is not None:
|
||||||
@@ -266,10 +270,11 @@ class BrickRow:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def splash_screen(data_rows: list[int]):
|
def splash_screen(data_rows: list[int], text: list[str]):
|
||||||
"""
|
"""
|
||||||
Display a splash screen using the bits in the data_rows.
|
Display a splash screen using the bits in the data_rows.
|
||||||
Args: data_rows (list[int]): List of hex values to display as blocks.
|
Args: data_rows (list[int]): List of hex values to display as blocks.
|
||||||
|
text (list[str]): List of strings to display as text.
|
||||||
"""
|
"""
|
||||||
global fbuf, buffer, buffer_width, buffer_height, joystick, render_frame
|
global fbuf, buffer, buffer_width, buffer_height, joystick, render_frame
|
||||||
fbuf.fill(BLACK)
|
fbuf.fill(BLACK)
|
||||||
@@ -278,21 +283,21 @@ def splash_screen(data_rows: list[int]):
|
|||||||
start_y = 20
|
start_y = 20
|
||||||
|
|
||||||
for row_index, hex_value in enumerate(data_rows):
|
for row_index, hex_value in enumerate(data_rows):
|
||||||
binary = bin(hex_value)[2:] # Convert to binary
|
|
||||||
binary = '{:0>22}'.format(binary) # Pad to 22 columns
|
|
||||||
if 0 <= row_index <= 1:
|
if 0 <= row_index <= 1:
|
||||||
color = RED
|
color = RED
|
||||||
elif 2 <= row_index <= 4:
|
elif 2 <= row_index <= 4:
|
||||||
color = YELLOW
|
color = YELLOW
|
||||||
else:
|
else:
|
||||||
color = GREEN
|
color = GREEN
|
||||||
for bit_index, bit in enumerate(binary):
|
|
||||||
if bit == '1': # Only draw a block for '1'
|
for bit_index in range(22): # Iterate over 22 bits
|
||||||
|
if (hex_value >> (21 - bit_index)) & 1:
|
||||||
x = start_x + bit_index * (SPLASH_WIDTH + SPLASH_PADDING)
|
x = start_x + bit_index * (SPLASH_WIDTH + SPLASH_PADDING)
|
||||||
y = start_y + row_index * (SPLASH_WIDTH + SPLASH_PADDING)
|
y = start_y + row_index * (SPLASH_WIDTH + SPLASH_PADDING)
|
||||||
fbuf.fill_rect(x, y, SPLASH_WIDTH, SPLASH_HEIGHT, color)
|
fbuf.fill_rect(x, y, SPLASH_WIDTH, SPLASH_HEIGHT, color)
|
||||||
fbuf.text("Press A to start", 5, 100, WHITE)
|
|
||||||
fbuf.text("Press B to exit", 5, 120, WHITE)
|
fbuf.text(text[0], 5, 100, WHITE)
|
||||||
|
fbuf.text(text[1], 5, 120, WHITE)
|
||||||
|
|
||||||
# Wait for the frame to be rendered & update the display
|
# Wait for the frame to be rendered & update the display
|
||||||
while render_frame:
|
while render_frame:
|
||||||
@@ -300,52 +305,71 @@ def splash_screen(data_rows: list[int]):
|
|||||||
display.blit_buffer(buffer, 0, 0, buffer_width, buffer_height)
|
display.blit_buffer(buffer, 0, 0, buffer_width, buffer_height)
|
||||||
|
|
||||||
|
|
||||||
|
def create_bricks() -> list[BrickRow]:
|
||||||
|
bricks = []
|
||||||
|
for row in range(ROWS):
|
||||||
|
if row == 0:
|
||||||
|
color = RED
|
||||||
|
elif row == 1:
|
||||||
|
color = YELLOW
|
||||||
|
else:
|
||||||
|
color = GREEN
|
||||||
|
bricks.append(
|
||||||
|
BrickRow(BRICK_WIDTH,
|
||||||
|
BRICK_HEIGHT,
|
||||||
|
BRICK_PADDING,
|
||||||
|
10 + row * (BRICK_HEIGHT + BRICK_PADDING),
|
||||||
|
color))
|
||||||
|
return bricks
|
||||||
|
|
||||||
|
|
||||||
|
def create_lives(lives: int) -> list[Ball]:
|
||||||
|
"""
|
||||||
|
Create a list of small balls to represent lives
|
||||||
|
Args: lives (int): Number of lives left
|
||||||
|
"""
|
||||||
|
lives_balls = []
|
||||||
|
for i in range(0, lives):
|
||||||
|
life_ball = Ball(Paddle(), radius=3, color=WHITE)
|
||||||
|
life_ball.x = 5 + (i - 1) * 7
|
||||||
|
life_ball.y = 7
|
||||||
|
life_ball.x_speed = 0
|
||||||
|
lives_balls.append(life_ball)
|
||||||
|
return lives_balls
|
||||||
|
|
||||||
|
|
||||||
def main_loop():
|
def main_loop():
|
||||||
global fbuf, buffer, buffer_width, buffer_height, joystick
|
global fbuf, buffer, buffer_width, buffer_height, joystick
|
||||||
global render_frame
|
global render_frame
|
||||||
|
|
||||||
state = 0 # 0 = start screen, 1 = game, 2 = game over, 3 = game win
|
game_state = START_SCREEN # Start at the splash screen
|
||||||
|
paddle = Paddle()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
if state == 0: # Startup screen & init game state
|
if game_state == START_SCREEN: # Startup screen & init game state
|
||||||
bricks = []
|
# Generate bricks
|
||||||
for row in range(ROWS):
|
bricks = create_bricks()
|
||||||
if row == 0:
|
lives = 3
|
||||||
color = RED
|
lives_balls = create_lives(lives)
|
||||||
elif row == 1:
|
|
||||||
color = YELLOW
|
|
||||||
else:
|
|
||||||
color = GREEN
|
|
||||||
bricks.append(
|
|
||||||
BrickRow(BRICK_WIDTH,
|
|
||||||
BRICK_HEIGHT,
|
|
||||||
BRICK_PADDING,
|
|
||||||
10 + row * (BRICK_HEIGHT + BRICK_PADDING),
|
|
||||||
color))
|
|
||||||
score = 0
|
score = 0
|
||||||
lives = 3
|
|
||||||
|
|
||||||
paddle = Paddle()
|
# Initialize paddle and ball
|
||||||
ball = Ball(paddle, radius=5, color=WHITE)
|
ball = Ball(paddle, radius=5, color=WHITE)
|
||||||
# Create a list of small balls to represent lives
|
paddle.width = PADDLE_WIDTH
|
||||||
lives_balls = []
|
paddle.height = PADDLE_HEIGHT
|
||||||
for i in range(0, lives):
|
|
||||||
life_ball = Ball(paddle, radius=3, color=WHITE)
|
|
||||||
life_ball.x = 5 + (i - 1) * 7
|
|
||||||
life_ball.y = 7
|
|
||||||
life_ball.x_speed = 0
|
|
||||||
lives_balls.append(life_ball)
|
|
||||||
|
|
||||||
render_frame = False
|
render_frame = False
|
||||||
splash_screen([0x060046, 0x056B54, 0x054A64, 0x064A46, 0x054A62, 0x054A52, 0x074B56])
|
splash_screen(
|
||||||
|
[0x060046, 0x056B54, 0x054A64, 0x064A46, 0x054A62, 0x054A52, 0x074B56],
|
||||||
if joystick.button_a() == 0: # Transition to game state when A is pressed
|
["Press A to start", "Press B to exit"]
|
||||||
state = 1
|
)
|
||||||
lives = 3
|
|
||||||
score = 0
|
|
||||||
|
|
||||||
elif state == 1 and lives > 0 and score < 28: # Game state
|
if joystick.button_a() == 0: # Transition to PLAYING state when A is pressed
|
||||||
|
game_state = PLAYING
|
||||||
|
sleep_us(DEBOUNCE) # Debounce delay
|
||||||
|
|
||||||
|
elif game_state == PLAYING and lives > 0 and score < 28: # Game loop
|
||||||
paddle.update()
|
paddle.update()
|
||||||
if ball.update_pos(): # If ball is out of bounds, lose a life and reset ball position
|
if ball.update_pos(): # If ball is out of bounds, lose a life and reset ball position
|
||||||
lives -= 1
|
lives -= 1
|
||||||
@@ -372,30 +396,45 @@ def main_loop():
|
|||||||
# Start SPI handler on core 1
|
# Start SPI handler on core 1
|
||||||
spi_thread = _thread.start_new_thread(render_thread, ())
|
spi_thread = _thread.start_new_thread(render_thread, ())
|
||||||
|
|
||||||
if state == 1 and (lives == 0 or score == 28): # Game over or win:
|
elif game_state == PLAYING and (lives == 0 or score == 28): # Game over or win
|
||||||
if lives > 0:
|
if lives > 0:
|
||||||
state= 3 # Winning state
|
game_state = GAME_NEXT_LEVEL # Transition to next level
|
||||||
else:
|
else:
|
||||||
state = 2 # Losing state
|
game_state = GAME_OVER # Losing state
|
||||||
if state == 2: # Game over screen
|
|
||||||
splash_screen([0x0276DC, 0x025490, 0x025494, 0x0256DC, 0x025298, 0x025294, 0x0376D4])
|
|
||||||
|
|
||||||
if state == 3: # Game win screen
|
if game_state == GAME_OVER: # Game over screen
|
||||||
splash_screen([0x04548, 0x04548, 0x04568, 0x05578, 0x05558, 0x05548, 0x03948])
|
splash_screen(
|
||||||
|
[0x0276DC, 0x025490, 0x025494, 0x0256DC, 0x025298, 0x025294, 0x0376D4],
|
||||||
|
["Press A to restart", "Press B to exit"]
|
||||||
|
)
|
||||||
|
if joystick.button_a() == 0: # Restart game when A is pressed
|
||||||
|
game_state = START_SCREEN
|
||||||
|
sleep_us(DEBOUNCE)
|
||||||
|
|
||||||
if state != 1 and joystick.button_a() == 0: # Transition to start state when A is pressed
|
if game_state == GAME_NEXT_LEVEL: # Next level screen
|
||||||
state = 0
|
splash_screen(
|
||||||
sleep_us(1_000_000) # Debounce delay
|
[0x04548, 0x04548, 0x04568, 0x05578, 0x05558, 0x05548, 0x03948],
|
||||||
|
["Press A for next level", "Press B to exit"]
|
||||||
|
)
|
||||||
|
if joystick.button_a() == 0: # Start next level when A is pressed
|
||||||
|
# Reinitialize bricks and ball for the next level
|
||||||
|
bricks = create_bricks()
|
||||||
|
ball.reset_pos(paddle)
|
||||||
|
paddle.width = max(PADDLE_WIDTH - 10, PADDLE_WIDTH // 2) # Decrease paddle size
|
||||||
|
paddle.height = PADDLE_HEIGHT
|
||||||
|
game_state = PLAYING
|
||||||
|
sleep_us(DEBOUNCE)
|
||||||
|
|
||||||
if joystick.button_b() == 0: # Exit game when B is pressed
|
if joystick.button_b() == 0: # Exit game when B is pressed
|
||||||
break
|
break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def render_thread():
|
def render_thread():
|
||||||
global fbuf, buffer, buffer_width, buffer_height, render_frame, spi
|
""""Threaded function to handle SPI rendering on a separate core."""
|
||||||
global display, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_ROTATION
|
global fbuf, buffer, buffer_width, buffer_height, render_frame
|
||||||
|
global display, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_ROTATION
|
||||||
|
|
||||||
display.blit_buffer(buffer, 0, 0, buffer_width, buffer_height)
|
display.blit_buffer(buffer, 0, 0, buffer_width, buffer_height)
|
||||||
fbuf.fill(0)
|
fbuf.fill(0)
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
from machine import Pin
|
||||||
|
|
||||||
|
# Joystick class to handle joystick input
|
||||||
|
class Joystick:
|
||||||
|
def __init__(self):
|
||||||
|
# Map buttons
|
||||||
|
self.button_a = Pin(15, Pin.IN, Pin.PULL_UP)
|
||||||
|
self.button_b = Pin(17, Pin.IN, Pin.PULL_UP)
|
||||||
|
# Map joystick
|
||||||
|
self.joy_up = Pin(2, Pin.IN, Pin.PULL_UP)
|
||||||
|
self.joy_down = Pin(18, Pin.IN, Pin.PULL_UP)
|
||||||
|
self.joy_left = Pin(16, Pin.IN, Pin.PULL_UP)
|
||||||
|
self.joy_right = Pin(20, Pin.IN, Pin.PULL_UP)
|
||||||
|
self.joy_click = Pin(3, Pin.IN, Pin.PULL_UP)
|
||||||
|
|
||||||
|
|
||||||
|
def color565(red: int, green: int, blue: int) -> int:
|
||||||
|
"""Convert RGB888 to RGB565."""
|
||||||
|
return (
|
||||||
|
(((green & 0b00011100) << 3) + ((red & 0b11111000) >> 3) << 8)
|
||||||
|
+ (blue & 0b11111000)
|
||||||
|
+ ((green & 0b11100000) >> 5)
|
||||||
|
)
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
from machine import Pin
|
|
||||||
class Joystick:
|
|
||||||
def __init__(self):
|
|
||||||
# Map buttons
|
|
||||||
self.button_a = Pin(15, Pin.IN, Pin.PULL_UP)
|
|
||||||
self.button_b = Pin(17, Pin.IN, Pin.PULL_UP)
|
|
||||||
# Map joystick
|
|
||||||
self.joy_up = Pin(2,Pin.IN, Pin.PULL_UP)
|
|
||||||
self.joy_down = Pin(18,Pin.IN, Pin.PULL_UP)
|
|
||||||
self.joy_left = Pin(16 ,Pin.IN, Pin.PULL_UP)
|
|
||||||
self.joy_right = Pin(20 ,Pin.IN, Pin.PULL_UP)
|
|
||||||
self.joy_click = Pin(3, Pin.IN, Pin.PULL_UP)
|
|
||||||
Reference in New Issue
Block a user