[fix] Small errors
- Ball can no longer lock to paddle - Brick edges are part of the brick
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Program Documentation
|
||||
|
||||
## 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.
|
||||
|
||||
## 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.
|
||||
|
||||
## Multithreading
|
||||
|
||||
The program uses multithreading to handle the game logic and the display updates separately. The `threading` module is used to create and manage the threads. The game logic is run in a separate thread from the display updates to ensure smooth gameplay and responsive controls.
|
||||
|
||||
|
||||
## Game Logic
|
||||
|
||||
The game logic is implemented in the `game_loop` function. This function runs in a separate thread and handles the following tasks:
|
||||
- Updating the game state based on user input and game rules
|
||||
- Generating new obstacles and updating their positions
|
||||
- Checking for collisions between the character and obstacles
|
||||
- Updating the score based on the player's performance
|
||||
- Sending the updated game state to the display thread for rendering
|
||||
@@ -0,0 +1,32 @@
|
||||
# Breakout Game for Raspberry Pi Pico
|
||||
|
||||
This is a simple Breakout game implemented in MicroPython for the Raspberry Pi Pico. The game uses the Pico-LCD-1.14 dDisplay for graphics and input.
|
||||
|
||||
|
||||
## Features
|
||||
- Classic Breakout gameplay
|
||||
- Simple and intuitive controls
|
||||
- Basic collision detection
|
||||
- Score tracking
|
||||
- Splash screen and game over screens
|
||||
|
||||
|
||||
## Requirements
|
||||
- Raspberry Pi Pico
|
||||
- Pico-LCD-1.14 display
|
||||
- MicroPython firmware installed on the Pico
|
||||
|
||||
|
||||
## Installation and Setup
|
||||
|
||||
1. Connect the Pico-LCD-1.14 display to the Raspberry Pi Pico following the wiring diagram provided in the display's documentation.
|
||||
|
||||
2. Download the MicroPython firmware for the Raspberry Pi Pico from the official MicroPython website and install it on the Pico. You can use the Thonny IDE to upload the firmware.
|
||||
|
||||
3. Clone or download this repository to your local machine.
|
||||
|
||||
4. Open the Thonny IDE and connect to your Raspberry Pi Pico.
|
||||
|
||||
5. Copy the contents of the repository to the Pico's file system. You can do this by dragging and dropping the files from your local machine to the Thonny file explorer.
|
||||
|
||||
6. Once the files are copied, reset the Pico to start the game.
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"name": "Mpy Remote Workspace",
|
||||
"uri": "pico:"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"python.languageServer": "Pylance"
|
||||
}
|
||||
}
|
||||
+45
-40
@@ -136,10 +136,15 @@ class Paddle:
|
||||
self.draw()
|
||||
|
||||
def hit(self, ball: Ball) -> bool:
|
||||
"""Check if the ball hits the paddle."""
|
||||
return (
|
||||
self.x < ball.x < self.x + self.width
|
||||
and self.y < ball.y < self.y + self.height)
|
||||
"""Check if the ball hits the paddle and adjust its position."""
|
||||
if (
|
||||
self.x <= ball.x <= self.x + self.width
|
||||
and self.y <= ball.y + ball.radius <= self.y + self.height
|
||||
):
|
||||
# Adjust the ball's position to be just above the paddle
|
||||
ball.y = self.y - ball.radius - 2
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Ball:
|
||||
@@ -163,11 +168,11 @@ class Ball:
|
||||
self.y = paddle.y - radius - 2 # Place the ball just above the paddle
|
||||
|
||||
def reset_pos(self, paddle: Paddle):
|
||||
"""Reset ball position to the center of the screen.
|
||||
"""Reset ball position to the center of the paddle.
|
||||
Args: Paddle: The paddle object to position the ball on.
|
||||
"""
|
||||
self.x = SCREEN_HEIGHT // 2
|
||||
self.y = SCREEN_WIDTH // 2
|
||||
self.y = SCREEN_WIDTH // 2 - self.radius - 2
|
||||
self.x_speed = BALL_SPEED
|
||||
self.y_speed = -BALL_SPEED
|
||||
|
||||
@@ -181,7 +186,7 @@ class Ball:
|
||||
self.x = 0
|
||||
self.x_speed = -self.x_speed
|
||||
elif self.x > SCREEN_HEIGHT:
|
||||
self.x = SCREEN_HEIGHT
|
||||
self.x = SCREEN_HEIGHT - self.radius
|
||||
self.x_speed = -self.x_speed
|
||||
|
||||
# Bounce off top screen edge
|
||||
@@ -255,7 +260,7 @@ class BrickRow:
|
||||
"""
|
||||
for i, brick in enumerate(self.bricks):
|
||||
if brick is not None:
|
||||
if (brick.x < ball.x < brick.x + brick.width) and (brick.y < ball.y < brick.y + brick.height):
|
||||
if (brick.x <= ball.x <= brick.x + brick.width) and (brick.y <= ball.y <= brick.y + brick.height):
|
||||
# Remove the brick by setting it to None
|
||||
self.bricks[i] = None
|
||||
return True
|
||||
@@ -299,40 +304,40 @@ def main_loop():
|
||||
global fbuf, buffer, buffer_width, buffer_height, joystick
|
||||
global render_frame
|
||||
|
||||
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))
|
||||
score = 0
|
||||
lives = 3
|
||||
|
||||
paddle = Paddle()
|
||||
ball = Ball(paddle, radius=5, color=WHITE)
|
||||
# Create a list of small balls to represent lives
|
||||
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)
|
||||
|
||||
render_frame = False
|
||||
state = 0 # 0 = start screen, 1 = game, 2 = game over, 3 = game win
|
||||
|
||||
try:
|
||||
while True:
|
||||
if state == 0: # Startup screen
|
||||
if state == 0: # Startup screen & init game state
|
||||
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))
|
||||
score = 0
|
||||
lives = 3
|
||||
|
||||
paddle = Paddle()
|
||||
ball = Ball(paddle, radius=5, color=WHITE)
|
||||
# Create a list of small balls to represent lives
|
||||
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)
|
||||
|
||||
render_frame = False
|
||||
splash_screen([0x060046, 0x056B54, 0x054A64, 0x064A46, 0x054A62, 0x054A52, 0x074B56])
|
||||
|
||||
if joystick.button_a() == 0: # Transition to game state when A is pressed
|
||||
@@ -345,10 +350,10 @@ def main_loop():
|
||||
if ball.update_pos(): # If ball is out of bounds, lose a life and reset ball position
|
||||
lives -= 1
|
||||
lives_balls.pop()
|
||||
ball.reset_pos(paddle) # Reset ball position to the center of the screen
|
||||
ball.reset_pos(paddle) # Reset ball position to the center of the paddle
|
||||
|
||||
if paddle.hit(ball):
|
||||
ball.y_speed = -ball.y_speed
|
||||
ball.y_speed = -abs(ball.y_speed)
|
||||
for row in bricks:
|
||||
if row.hit(ball):
|
||||
ball.y_speed = -ball.y_speed
|
||||
|
||||
Reference in New Issue
Block a user