如何实现Pygame中物体的错峰生成?附问题代码求助
问题修复:下落物体游戏的多故障排查
核心问题分析
你的游戏出现的「仅顶部8个方块、每次仅一个下落」问题,主要由缩进错误和逻辑偏差导致,具体如下:
update_enemies_pos函数中return score缩进错误,导致每次只处理第一个敌人就返回,其余敌人位置完全不更新collision_check函数中return False缩进错误,导致仅检查第一个敌人就判定无碰撞- 敌人初始高度固定为10,无法实现「不同高度下落」的需求
- 碰撞检测函数的参数顺序不匹配,导致碰撞判断逻辑完全错误
修复后的完整代码
import pygame import random import sys import time import os from tkinter import * from tkinter import messagebox print(os.getcwd()) pygame.init() def game(): print("") WIDTH = 800 HEIGHT = 600 TRASH = (110, 110, 110) SEA_TURTLE = (108,170,180) player_pos = [400, 475] player_size = 50 game_over = False screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 图片加载容错处理 try: my_image = pygame.image.load("SeaTurtle1.png").convert_alpha() except: my_image = pygame.Surface((player_size, player_size)) my_image.fill(SEA_TURTLE) enemy_size = 40 SPEED = 11 FPS = 120 # 初始敌人随机从屏幕上方下落 enemy_pos = [random.randint(0, WIDTH - enemy_size), random.randint(-HEIGHT//2, 0)] enemy_list = [enemy_pos] score = 0 clock = pygame.time.Clock() myFont = pygame.font.SysFont("DroidSans", 35) pygame.display.set_caption('Trash Dodge, Science Project, By: Benjamin Bernstein') pygame.mouse.set_visible(0) def drop_enemies(enemy_list): if len(enemy_list) < 9: x_pos = random.randint(0, WIDTH - enemy_size) # 随机生成屏幕外负y坐标,实现不同高度下落 y_pos = random.randint(-HEIGHT, 0) enemy_list.append([x_pos, y_pos]) def draw_enemies(enemy_list): for enemy_pos in enemy_list: pygame.draw.rect(screen, TRASH, (enemy_pos[0], enemy_pos[1], enemy_size, enemy_size)) def update_enemies_pos(enemy_list, score): for idx, enemy_pos in enumerate(enemy_list): if enemy_pos[1] >= 0 and enemy_pos[1] < HEIGHT: enemy_pos[1] += SPEED else: enemy_list.pop(idx) score += 1 # 移到循环外,确保所有敌人都被处理 return score def collision_check(enemy_list, player_pos): for enemy_pos in enemy_list: if detect_collision(player_pos, enemy_pos): return True # 移到循环外,确保遍历所有敌人 return False # 简化边缘检测函数 def edge_detection1(player_pos): return player_pos[0] > 750 def edge_detection2(player_pos): return player_pos[0] < 0 def detect_collision(player_pos, enemy_pos): p_x, p_y = player_pos e_x, e_y = enemy_pos # 简化轴对齐碰撞判断逻辑 return (p_x < e_x + enemy_size and p_x + player_size > e_x) and \ (p_y < e_y + enemy_size and p_y + player_size > e_y) while not game_over: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.KEYDOWN: x = player_pos[0] # 合并同类按键判断 if event.key in [pygame.K_LEFT, pygame.K_a, pygame.K_q]: x -= player_size elif event.key in [pygame.K_RIGHT, pygame.K_d]: x += player_size elif event.key == pygame.K_ESCAPE: sys.exit() player_pos = [x, player_pos[1]] screen.fill((108,170,180)) drop_enemies(enemy_list) score = update_enemies_pos(enemy_list, score) # 绘制分数 text = "Score: " + str(score) label = myFont.render(text, 1, (0, 0, 0)) screen.blit(label, (WIDTH - 120, HEIGHT - 40)) # 边缘 teleport 逻辑 if edge_detection1(player_pos): player_pos[0] = 0 if edge_detection2(player_pos): player_pos[0] = 750 # 碰撞判定 if collision_check(enemy_list, player_pos): time.sleep(1.4) Tk().wm_withdraw() game_over = True # 绘制元素 draw_enemies(enemy_list) player_rect = pygame.Rect(player_pos[0], player_pos[1], player_size, player_size) pygame.draw.rect(screen, SEA_TURTLE, player_rect) screen.blit(my_image, player_rect) clock.tick(FPS) pygame.display.update() ans = messagebox.askretrycancel("You died.", "You lose! This game shows how hard litter and trash makes it for sea turtles to survive. Make sure to pick up any litter and trash you see on the beach.") root = Tk() root.destroy() return ans while True: if not game(): break
关键修复点说明
- 修正缩进错误:将
update_enemies_pos和collision_check中的返回语句移到循环外部,确保所有敌人都被处理 - 实现随机下落高度:修改敌人初始y坐标为屏幕外随机负值,让敌人从不同高度下落
- 修正碰撞检测逻辑:调整参数顺序匹配函数定义,简化碰撞判断代码
- 优化代码细节:合并重复按键判断、添加图片加载容错、简化边缘检测函数
内容的提问来源于stack exchange,提问作者Benjamin Bernstein
相关产品推荐
相关产品推荐

