DAY 4 - jayce122003/day-1 GitHub Wiki

import pygame import random

Initialize pygame

pygame.init()

Screen settings

WIDTH, HEIGHT = 600, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Brick Breaker")

Load image

try: background_image = pygame.image.load("assets/ux.png") background_image = pygame.transform.scale(background_image, (WIDTH, HEIGHT)) except pygame.error: print("Error: Background image not found!") background_image = None

Colors

WHITE = (255, 255, 255) BLACK = (0, 0, 0) BLUE = (0, 0, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) YELLOW = (255, 255, 0)

Fonts

font = pygame.font.Font(None, 36)

def draw_text(text, x, y, color=WHITE): label = font.render(text, True, color) screen.blit(label, (x, y))

def draw_text_centered(text, y, color=WHITE): text_surface = font.render(text, True, color) text_x = (WIDTH - text_surface.get_width()) // 2 screen.blit(text_surface, (text_x, y))

def difficulty_selection(): selecting = True button_width, button_height = 180, 50 button_y_offset = HEIGHT - 180 spacing = 60

easy_rect = pygame.Rect((WIDTH - button_width) // 2, button_y_offset, button_width, button_height)
medium_rect = pygame.Rect((WIDTH - button_width) // 2, button_y_offset + spacing, button_width, button_height)
hard_rect = pygame.Rect((WIDTH - button_width) // 2, button_y_offset + 2 * spacing, button_width, button_height)

while selecting:
    screen.fill(BLACK)
    if background_image:
        screen.blit(background_image, (0, 0))

    draw_text_centered("SELECT LEVEL", HEIGHT // 1.6, BLACK)

    pygame.draw.rect(screen, GREEN, easy_rect, border_radius=50)
    pygame.draw.rect(screen, YELLOW, medium_rect, border_radius=50)
    pygame.draw.rect(screen, RED, hard_rect, border_radius=50)

    draw_text("Easy", easy_rect.centerx - 30, easy_rect.centery - 10, BLACK)
    draw_text("Medium", medium_rect.centerx - 45, medium_rect.centery - 10, BLACK)
    draw_text("Hard", hard_rect.centerx - 30, hard_rect.centery - 10, BLACK)

    pygame.display.flip()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if easy_rect.collidepoint(event.pos):
                return "Easy"
            if medium_rect.collidepoint(event.pos):
                return "Medium"
            if hard_rect.collidepoint(event.pos):
                return "Hard"

Game settings based on difficulty

selected_difficulty = difficulty_selection()

difficulty_settings = { "Easy": {"ball_speed": 3, "brick_rows": 5}, "Medium": {"ball_speed": 4, "brick_rows": 7}, "Hard": {"ball_speed": 5, "brick_rows": 9}, }

Paddle settings

PADDLE_WIDTH = 100 PADDLE_HEIGHT = 10 paddle_x = (WIDTH - PADDLE_WIDTH) // 2 paddle_y = HEIGHT - 50 paddle_speed = 7

Ball settings

BALL_RADIUS = 8 initial_ball_speed = difficulty_settings[selected_difficulty]["ball_speed"] balls = [{"x": WIDTH // 2, "y": HEIGHT // 2, "dx": random.choice([-initial_ball_speed, initial_ball_speed]), "dy": -initial_ball_speed}] falling_balls = []

Score & Level

score = 0 level = 1

def generate_bricks(rows): return [pygame.Rect(col * (BRICK_WIDTH + 5) + 5, row * (BRICK_HEIGHT + 5) + 5, BRICK_WIDTH, BRICK_HEIGHT) for row in range(rows) for col in range(BRICK_COLS)]

Brick settings

BRICK_COLS = 8 BRICK_WIDTH = WIDTH // BRICK_COLS - 5 BRICK_HEIGHT = 20 BRICK_ROWS = difficulty_settings[selected_difficulty]["brick_rows"] bricks = generate_bricks(BRICK_ROWS)

def game_over(): screen.fill(BLACK) draw_text("Game Over", WIDTH // 2 - 60, HEIGHT // 2) pygame.display.flip() pygame.time.delay(2000) pygame.quit() exit()

def next_level(): global bricks, level, balls, initial_ball_speed, score level += 1 score += 100 # Bonus for completing a level initial_ball_speed += 1 # Increase ball speed bricks = generate_bricks(BRICK_ROWS + level) # More bricks each level balls = [{"x": WIDTH // 2, "y": HEIGHT // 2, "dx": random.choice([-initial_ball_speed, initial_ball_speed]), "dy": -initial_ball_speed}]

Game loop

running = True while running: screen.fill(BLACK)

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False

# Move paddle
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and paddle_x > 0:
    paddle_x -= paddle_speed
if keys[pygame.K_RIGHT] and paddle_x < WIDTH - PADDLE_WIDTH:
    paddle_x += paddle_speed

paddle_rect = pygame.Rect(paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT)

# Move balls
for ball in balls[:]:
    ball["x"] += ball["dx"]
    ball["y"] += ball["dy"]
    
    if ball["x"] - BALL_RADIUS <= 0 or ball["x"] + BALL_RADIUS >= WIDTH:
        ball["dx"] = -ball["dx"]
    if ball["y"] - BALL_RADIUS <= 0:
        ball["dy"] = -ball["dy"]
    if paddle_rect.collidepoint(ball["x"], ball["y"] + BALL_RADIUS):
        ball["dy"] = -abs(ball["dy"])
    
    for brick in bricks[:]:
        if brick.collidepoint(ball["x"], ball["y"] + BALL_RADIUS):
            ball["dy"] = -ball["dy"]
            bricks.remove(brick)
            score += 10  # Increase score
            if random.random() < 0.3:
                falling_balls.append({"x": brick.centerx, "y": brick.bottom, "dy": 2})
            break
    
    if ball["y"] + BALL_RADIUS >= HEIGHT:
        balls.remove(ball)

for fb in falling_balls[:]:
    fb["y"] += fb["dy"]
    pygame.draw.circle(screen, YELLOW, (int(fb["x"]), int(fb["y"])), BALL_RADIUS)
    if paddle_rect.collidepoint(fb["x"], fb["y"]):
        balls.append({"x": fb["x"], "y": fb["y"], "dx": random.choice([-initial_ball_speed, initial_ball_speed]), "dy": -initial_ball_speed})
        falling_balls.remove(fb)
    elif fb["y"] >= HEIGHT:
        falling_balls.remove(fb)

if not balls:
    game_over()

if not bricks:
    next_level()

pygame.draw.rect(screen, BLUE, paddle_rect)
for ball in balls:
    pygame.draw.circle(screen, RED, (int(ball["x"]), int(ball["y"])), BALL_RADIUS)
for brick in bricks:
    pygame.draw.rect(screen, GREEN, brick)

draw_text(f"Score: {score}", 10, 10)
draw_text(f"Level: {level}", WIDTH - 100, 10)

pygame.display.flip()
pygame.time.delay(30)

pygame.quit()