如何将Pygame游戏菜单代码与基础游戏代码整合?
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:
- State Management: We use a
main()function to handle the menu, and when the start button is clicked, we callgame_loop()to run the game. After the game ends (collision), we return to the menu automatically. - Shared Constants: All reused values (like screen size, colors) are defined once at the top for easy editing.
- Reset Game Variables: Every time you start a new game, variables like
player_pos,enemy_list, andscoreare reset to their initial values. - Player Boundaries: Added code to keep the player from moving outside the screen.
- 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




