import streamlit as st from PIL import Image, ImageDraw # Streamlit setup st.set_page_config(page_title="Breakout Game", layout="centered") st.title("🎮 Breakout Game - Hugging Face Version") st.write("Control the paddle with your mouse or left/right arrow keys.") # Initialize game parameters WIDTH, HEIGHT = 800, 600 PADDLE_WIDTH, PADDLE_HEIGHT = 100, 15 BALL_RADIUS = 10 BRICK_ROWS, BRICK_COLS = 5, 8 BRICK_WIDTH = WIDTH // BRICK_COLS BRICK_HEIGHT = 30 # Session state for game variables if "paddle_x" not in st.session_state: st.session_state.paddle_x = WIDTH // 2 - PADDLE_WIDTH // 2 if "ball_pos" not in st.session_state: st.session_state.ball_pos = [WIDTH // 2, HEIGHT // 2] if "ball_speed" not in st.session_state: st.session_state.ball_speed = [4, -4] if "bricks" not in st.session_state: st.session_state.bricks = [ [col * BRICK_WIDTH, row * BRICK_HEIGHT] for row in range(BRICK_ROWS) for col in range(BRICK_COLS) ] if "score" not in st.session_state: st.session_state.score = 0 if "lives" not in st.session_state: st.session_state.lives = 3 if "paddle_speed" not in st.session_state: st.session_state.paddle_speed = 0 # Draw the game screen def draw_game(): # Create a blank canvas img = Image.new("RGB", (WIDTH, HEIGHT), "black") draw = ImageDraw.Draw(img) # Draw paddle paddle_y = HEIGHT - 40 draw.rectangle( [ (st.session_state.paddle_x, paddle_y), (st.session_state.paddle_x + PADDLE_WIDTH, paddle_y + PADDLE_HEIGHT), ], fill="white", ) # Draw ball ball_x, ball_y = st.session_state.ball_pos draw.ellipse( [ (ball_x - BALL_RADIUS, ball_y - BALL_RADIUS), (ball_x + BALL_RADIUS, ball_y + BALL_RADIUS), ], fill="red", ) # Draw bricks for brick in st.session_state.bricks: brick_x, brick_y = brick draw.rectangle( [(brick_x, brick_y), (brick_x + BRICK_WIDTH - 2, brick_y + BRICK_HEIGHT - 2)], fill="blue", ) return img # Update game state def update_game(): # Move paddle continuously st.session_state.paddle_x += st.session_state.paddle_speed if st.session_state.paddle_x < 0: st.session_state.paddle_x = 0 if st.session_state.paddle_x > WIDTH - PADDLE_WIDTH: st.session_state.paddle_x = WIDTH - PADDLE_WIDTH # Move ball ball_x, ball_y = st.session_state.ball_pos speed_x, speed_y = st.session_state.ball_speed ball_x += speed_x ball_y += speed_y # Ball collision with walls if ball_x - BALL_RADIUS <= 0 or ball_x + BALL_RADIUS >= WIDTH: speed_x = -speed_x if ball_y - BALL_RADIUS <= 0: speed_y = -speed_y # Ball collision with paddle paddle_y = HEIGHT - 40 if ( paddle_y <= ball_y + BALL_RADIUS <= paddle_y + PADDLE_HEIGHT and st.session_state.paddle_x <= ball_x <= st.session_state.paddle_x + PADDLE_WIDTH ): speed_y = -speed_y # Ball collision with bricks new_bricks = [] for brick in st.session_state.bricks: brick_x, brick_y = brick if not ( brick_x <= ball_x <= brick_x + BRICK_WIDTH and brick_y <= ball_y <= brick_y + BRICK_HEIGHT ): new_bricks.append(brick) else: speed_y = -speed_y st.session_state.score += 10 st.session_state.bricks = new_bricks # Ball out of bounds if ball_y + BALL_RADIUS >= HEIGHT: st.session_state.lives -= 1 ball_x, ball_y = WIDTH // 2, HEIGHT // 2 speed_x, speed_y = 4, -4 # Update ball position and speed st.session_state.ball_pos = [ball_x, ball_y] st.session_state.ball_speed = [speed_x, speed_y] # Display the game st.image(draw_game(), use_column_width=True) # Display score and lives st.write(f"**Score**: {st.session_state.score}") st.write(f"**Lives**: {st.session_state.lives}") # Game over if st.session_state.lives <= 0: st.write("**Game Over! Refresh the page to restart.**") else: # Handle user input col1, col2, col3 = st.columns(3) with col1: if st.button("⬅️ Move Left"): st.session_state.paddle_speed = -10 with col2: if st.button("🔄 Stop Paddle"): st.session_state.paddle_speed = 0 with col3: if st.button("➡️ Move Right"): st.session_state.paddle_speed = 10 # Auto-update game state update_game() st.experimental_rerun()