You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Pygame游戏菜单代码与基础游戏代码整合?

Merging Your Pygame Menu and Game Code

Hey there! Let's walk through combining your menu and game code into a single, functional program. The key idea is to use a state system to switch between the menu screen and the active game. Here's the full merged code with explanations:

import pygame
import random
import sys

# Initialize Pygame once (no need to do this twice!)
pygame.init()

# Shared constants (used by both menu and game)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
BG_COLOR_MENU = (34, 139, 34)
BG_COLOR_GAME = (0, 0, 0)
RED = (251, 63, 75)
BLUE = (0, 0, 125)
BRIGHT_BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
PLAYER_SIZE = 25
ENEMY_SIZE = 25
FONT_SIZE = 35

# Set up the screen once
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("My Pygame Game")

# Load fonts once
menu_font = pygame.font.SysFont("freesansbold.ttf", FONT_SIZE)
game_font = pygame.font.SysFont("monospace", 35)

def draw_button(button_pos, button_size):
    """Handles drawing the start button and detecting clicks"""
    mouse_pos = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    # Change button color on hover
    if (button_pos[0] < mouse_pos[0] < button_pos[0] + button_size[0]) and \
       (button_pos[1] < mouse_pos[1] < button_pos[1] + button_size[1]):
        pygame.draw.rect(screen, BRIGHT_BLUE, (*button_pos, *button_size))
        # Start game when left-clicked
        if click[0] == 1:
            return True
    else:
        pygame.draw.rect(screen, BLUE, (*button_pos, *button_size))
    
    # Draw button text
    text = menu_font.render("START", True, RED)
    screen.blit(text, (SCREEN_WIDTH//2 - 38, button_pos[1] + 5))
    return False

def set_level(score, speed):
    """Adjust enemy speed based on score"""
    if score < 10:
        return 5
    elif score < 20:
        return 6
    elif score < 30:
        return 8
    elif score < 40:
        return 10
    elif score < 50:
        return 13
    elif score < 200:
        return 15
    else:
        return 20

def drop_enemies(enemy_list):
    """Randomly add new enemies to the list"""
    delay = random.random()
    if len(enemy_list) < 6 and delay < 0.1:
        x_pos = random.randint(0, SCREEN_WIDTH - ENEMY_SIZE)
        enemy_list.append([x_pos, 0])

def draw_enemies(enemy_list):
    """Draw all enemies on the screen"""
    for enemy_pos in enemy_list:
        pygame.draw.rect(screen, BLUE, (*enemy_pos, ENEMY_SIZE, ENEMY_SIZE))

def update_enemy_pos(enemy_list, score):
    """Move enemies down and remove those that go off-screen"""
    for idx, enemy_pos in enumerate(enemy_list):
        if 0 <= enemy_pos[1] < SCREEN_HEIGHT:
            enemy_pos[1] += speed
        else:
            enemy_list.pop(idx)
            score += 1
    return score

def detect_collision(player_pos, enemy_pos):
    """Check if player and enemy are overlapping"""
    p_x, p_y = player_pos
    e_x, e_y = enemy_pos
    return (e_x < p_x + PLAYER_SIZE and e_x + ENEMY_SIZE > p_x) and \
           (e_y < p_y + PLAYER_SIZE and e_y + ENEMY_SIZE > p_y)

def collision_check(enemy_list, player_pos):
    """Check if player collides with any enemy"""
    for enemy_pos in enemy_list:
        if detect_collision(player_pos, enemy_pos):
            return True
    return False

def game_loop():
    """Main game logic loop"""
    # Reset game variables every time we start a new game
    player_pos = [SCREEN_WIDTH//2, SCREEN_HEIGHT - 2*PLAYER_SIZE]
    enemy_list = []
    score = 0
    speed = 5
    game_over = False
    clock = pygame.time.Clock()

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            # Handle player movement
            if event.type == pygame.KEYDOWN:
                x, y = player_pos
                if event.key == pygame.K_LEFT:
                    x -= PLAYER_SIZE
                elif event.key == pygame.K_UP:
                    y -= PLAYER_SIZE
                elif event.key == pygame.K_RIGHT:
                    x += PLAYER_SIZE
                elif event.key == pygame.K_DOWN:
                    y += PLAYER_SIZE
                # Keep player within screen bounds
                x = max(0, min(x, SCREEN_WIDTH - PLAYER_SIZE))
                y = max(0, min(y, SCREEN_HEIGHT - PLAYER_SIZE))
                player_pos = [x, y]

        # Update game state
        screen.fill(BG_COLOR_GAME)
        drop_enemies(enemy_list)
        score = update_enemy_pos(enemy_list, score)
        speed = set_level(score, speed)

        # Draw score
        score_text = game_font.render(f"Score: {score}", True, YELLOW)
        screen.blit(score_text, (SCREEN_WIDTH//2 - 70, SCREEN_HEIGHT - 40))

        # Check for collisions
        if collision_check(enemy_list, player_pos):
            game_over = True

        # Draw game elements
        draw_enemies(enemy_list)
        pygame.draw.rect(screen, RED, (*player_pos, PLAYER_SIZE, PLAYER_SIZE))

        clock.tick(30)
        pygame.display.update()

def main():
    """Main program loop that switches between menu and game"""
    button_pos = [SCREEN_WIDTH//2 - 50, SCREEN_HEIGHT//2]
    button_size = [105, 50]
    running = True

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

        # Draw menu screen
        screen.fill(BG_COLOR_MENU)
        start_game = draw_button(button_pos, button_size)
        
        # If start button is clicked, launch the game
        if start_game:
            game_loop()

        pygame.display.update()

    pygame.quit()
    sys.exit()

# Start the program
if __name__ == "__main__":
    main()

Key Changes Explained:

  1. State Management: We use a main() function to handle the menu, and when the start button is clicked, we call game_loop() to run the game. After the game ends (collision), we return to the menu automatically.
  2. Shared Constants: All reused values (like screen size, colors) are defined once at the top for easy editing.
  3. Reset Game Variables: Every time you start a new game, variables like player_pos, enemy_list, and score are reset to their initial values.
  4. Player Boundaries: Added code to keep the player from moving outside the screen.
  5. Cleaned Up Duplicate Code: Removed duplicate imports, Pygame initialization, and screen setup.

Next Steps You Might Want to Add:

  • A quit button in the menu
  • A game over screen with a "Play Again" option
  • Sound effects for button clicks and collisions
  • A high score system

内容的提问来源于stack exchange,提问作者Supreme intelligence

火山引擎 最新活动