You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame开发2D格斗游戏时List index out of range错误复现求助

解决Pygame格斗游戏中的List Index Out of Range错误

看起来你遇到的问题和之前根源类似,但这次的触发点可能更隐蔽——本质要么是动画图片列表(ani_stand或ani_walk)为空,要么是update函数里的索引计算逻辑出现了越界。我来帮你一步步排查修复:

1. 先解决初始化时的索引越界问题

你在__init__里直接访问self.ani_stand[0]和self.ani_walk[0],但如果glob.glob没找到匹配的图片文件,这两个列表就会是空的,自然抛出索引越界错误。这大概率是路径写法或文件命名/位置的问题。

修复步骤:

  • 修正路径写法:Windows下的路径可以用原始字符串(加r前缀)避免转义问题,或者用os.path模块拼接(更适配跨平台):
    import os
    # 用os.path拼接路径,适配所有操作系统
    stand_path = os.path.join("characters", "Naruto", "Standing", "naruto_s*.png")
    self.ani_stand = glob.glob(stand_path)
    
  • 添加空列表检查:在访问列表索引前,先确认列表不为空,提前抛出明确的错误提示:
    self.ani_stand.sort()
    if not self.ani_stand:
        raise FileNotFoundError("未找到站立动画图片!请检查路径是否正确,或图片文件名是否以'naruto_s'开头。")
    self.ani_max = len(self.ani_stand)-1
    self.img_stand = pygame.image.load(self.ani_stand[0])
    
    # 行走动画做同样的检查
    self.ani_walk.sort()
    if not self.ani_walk:
        raise FileNotFoundError("未找到行走动画图片!请检查路径是否正确,或图片文件名是否以'naruto_w'开头。")
    self.ani_max_walk = len(self.ani_walk)-1
    self.img_walk = pygame.image.load(self.ani_walk[0])
    

2. 修复update函数中的索引逻辑漏洞

看你update的else块,这里有两个明显的问题会导致索引越界:

  • 你写了self.img = pygame.image.load(self.ani_stand[self.ani_pos-1]),如果self.ani_pos是0,那self.ani_pos-1就是-1,直接触发越界。
  • self.count变量没有递增或重置逻辑,会导致动画帧切换逻辑混乱,进而引发索引异常。

修正后的update函数:

def update(self, pos):
    if pos != 0:
        self.ani_speed -= 1
        self.x += pos
        if self.ani_speed == 0:
            self.img = pygame.image.load(self.ani_walk[self.ani_pos])
            self.ani_speed = self.ani_speed_init
            # 简化帧切换逻辑,避免越界
            self.ani_pos = 0 if self.ani_pos == self.ani_max_walk else self.ani_pos + 1
    else:
        self.ani_speed -= 1
        if self.moving:
            self.ani_speed = self.ani_speed_init
        # 修复count的递增和重置逻辑
        if self.count == 8:
            # 帧切换时确保不越界
            self.ani_pos = 0 if self.ani_pos >= self.ani_max else self.ani_pos + 1
            self.count = 0  # 重置计数器
        else:
            self.count += 1  # 计数器递增
        # 确保索引始终在有效范围内(0到ani_max)
        safe_frame_index = max(0, min(self.ani_pos, self.ani_max))
        self.img = pygame.image.load(self.ani_stand[safe_frame_index])

3. 额外优化:提前加载所有动画图片

你现在每次update都重新加载图片,不仅性能差,还可能因为重复处理路径引发意外错误。建议在__init__时就把所有图片加载到列表里,update时直接取用:

def __init__(self):
    self.x = 200
    self.y = 300
    self.y_change = 0
    self.ani_speed_init = 8
    self.ani_speed = self.ani_speed_init
    self.moving = True
    self.ani_pos = 0
    self.jumping = False
    self.velocity_index = 0
    self.count = 0

    # 提前加载站立动画所有图片
    stand_path = os.path.join("characters", "Naruto", "Standing", "naruto_s*.png")
    self.ani_stand_paths = glob.glob(stand_path)
    self.ani_stand_paths.sort()
    if not self.ani_stand_paths:
        raise FileNotFoundError("未找到站立动画图片!")
    # 一次性加载所有图片到列表
    self.ani_stand = [pygame.image.load(path) for path in self.ani_stand_paths]
    self.ani_max = len(self.ani_stand)-1
    self.img_stand = self.ani_stand[0]

    # 提前加载行走动画所有图片
    walk_path = os.path.join("characters", "Naruto", "Walk", "naruto_w*.png")
    self.ani_walk_paths = glob.glob(walk_path)
    self.ani_walk_paths.sort()
    if not self.ani_walk_paths:
        raise FileNotFoundError("未找到行走动画图片!")
    self.ani_walk = [pygame.image.load(path) for path in self.ani_walk_paths]
    self.ani_max_walk = len(self.ani_walk)-1
    self.img_walk = self.ani_walk[0]

    self.img = self.ani_stand[0]
    self.rect = self.img.get_rect()
    self.update(0)

# 然后update函数里直接取列表中的图片
def update(self, pos):
    if pos != 0:
        self.ani_speed -= 1
        self.x += pos
        if self.ani_speed == 0:
            self.img = self.ani_walk[self.ani_pos]
            self.ani_speed = self.ani_speed_init
            self.ani_pos = 0 if self.ani_pos == self.ani_max_walk else self.ani_pos + 1
    else:
        self.ani_speed -= 1
        if self.moving:
            self.ani_speed = self.ani_speed_init
        if self.count == 8:
            self.ani_pos = 0 if self.ani_pos >= self.ani_max else self.ani_pos + 1
            self.count = 0
        else:
            self.count += 1
        safe_frame_index = max(0, min(self.ani_pos, self.ani_max))
        self.img = self.ani_stand[safe_frame_index]

按照上面的步骤修复后,应该就能彻底解决索引越界的问题了。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:51:04