Pygame游戏开发报错:向Sprite Group添加对象失败求助
Pygame游戏报错修复方案
核心错误定位与修复
报错的直接原因是在world类的初始化方法中,你试图将Radiation类本身添加到精灵组,而非创建好的实例:
# 错误代码 rad = Radiation(col_count * tile_size, row_count * tile_size) rad_group.add(Radiation)
修正为:
# 正确代码 rad = Radiation(col_count * tile_size, row_count * tile_size) rad_group.add(rad)
其他需要修复的潜在问题
- 方法名拼写错误:
world类中的drow方法拼写错误,应为draw,否则主循环调用时会抛出属性错误:
# 修正前 def drow(self): # 修正后 def draw(self):
同时主循环中的world.drow()也要对应改为world.draw()。
- 精灵组未绘制:创建的
rad_group没有在主循环中绘制,导致辐射元素不会显示,需要在主循环中添加:
rad_group.draw(screen)
- Player类中引用World实例的问题:Player的
update方法中直接使用world.tile_list,后续代码结构调整容易出问题,建议在初始化Player时传入world实例:
# Player类初始化修改 class player(): def __init__(self, x, y, world): self.world = world # 其他原有代码... def update(self): # 遍历tile_list时改为 for tile in self.world.tile_list: # 原有碰撞检测代码...
创建Player实例时传入world:
world = world(world_data) player = player(950, 600, world)
修正后的关键代码片段
class world(): def __init__(self, data): self.tile_list = [] # 加载图片 dirt_image = pygame.image.load('images/dirt.png') dirt_l_image = pygame.image.load('images/dirt_l.jpg') row_count = 0 for row in data: col_count = 0 for tile in row: if tile == 1: img = pygame.transform.scale(dirt_image, (tile_size, tile_size)) img_rect = img.get_rect() img_rect.x = col_count * tile_size img_rect.y = row_count * tile_size tile = (img, img_rect) self.tile_list.append(tile) if tile == 2: img = pygame.transform.scale(dirt_l_image, (tile_size - 49, tile_size)) img_rect = img.get_rect() img_rect.x = col_count * tile_size img_rect.y = row_count * tile_size tile = (img, img_rect) self.tile_list.append(tile) if tile == 3: rad = Radiation(col_count * tile_size, row_count * tile_size) rad_group.add(rad) # 修正为添加实例rad col_count += 1 row_count += 1 def draw(self): # 修正方法名 for tile in self.tile_list: screen.blit(tile[0], tile[1]) class player(): def __init__(self, x, y, world): self.world = world self.images_right = [] self.images_left = [] self.index = 0 self.counter = 0 for num in range(1, 11): img_right = pygame.image.load(f'images/guy{num}.png') img_right = pygame.transform.scale(img_right, (150, 300)) img_left = pygame.transform.flip(img_right, True, False) self.images_right.append(img_right) self.images_left.append(img_left) self.image = self.images_right[self.index] self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.vel_y = 0 self.jumped = False self.width = self.image.get_width() self.height = self.image.get_height() self.direction = 0 def update(self): dx = 0 dy = 0 walk_cooldown = 10 # 按键处理 key = pygame.key.get_pressed() if key[pygame.K_SPACE] and self.jumped == False: self.vel_y = -15 self.jumped = True if key[pygame.K_SPACE] == False: self.jumped = False if key[pygame.K_LEFT]: dx -= 1 self.counter += 1 self.direction = -1 if key[pygame.K_RIGHT]: dx += 1 self.counter += 1 self.direction = 1 if key[pygame.K_RIGHT] == False and key[pygame.K_LEFT] == False: self.counter = 0 self.index = 0 if self.direction == 1: self.image = self.images_right[self.index] if self.direction == -1: self.image = self.images_left[self.index] # 动画逻辑 if self.counter > walk_cooldown: self.counter = 0 self.index += 1 if self.index >= len(self.images_right): self.index = 0 if self.direction == 1: self.image = self.images_right[self.index] if self.direction == -1: self.image = self.images_left[self.index] # 重力 self.vel_y += 1 if self.vel_y > 10: self.vel_y = 10 dy += self.vel_y # 碰撞检测 for tile in self.world.tile_list: # X方向碰撞 if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height): dx = 0 # Y方向碰撞 if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height): # 跳跃时碰到顶部 if self.vel_y < 0: dy = tile[1].bottom - self.rect.top self.vel_y = 0 # 下落时碰到地面 elif self.vel_y >= 0: dy = tile[1].top - self.rect.bottom self.vel_y = 0 # 更新玩家坐标 self.rect.x += dx self.rect.y += dy if self.rect.bottom > screen_height: self.rect.bottom = screen_height dy = 0 # 绘制玩家 screen.blit(self.image, self.rect) # 实例创建与主循环 rad_group = pygame.sprite.Group() world = world(world_data) player = player(950, 600, world) bg_img = pygame.image.load('images/bg.jpg') sc_img = pygame.image.load('images/scale.png') run = True while run: clock.tick(fps) screen.blit(bg_img, (0, 0)) screen.blit(sc_img, (70, 20)) world.draw() rad_group.draw(screen) # 添加辐射精灵绘制 for event in pygame.event.get(): if event.type == pygame.QUIT: run = False player.update() pygame.display.update() pygame.quit()
内容的提问来源于stack exchange,提问作者Mohammed Alharbi
相关产品推荐
相关产品推荐

