Pygame报TypeError: Source objects must be a surface 两版本实现差异原因求解
两个版本核心差异
两个版本的本质区别是paths参数传递的内容类型,以及Asset类对self.images的存储类型处理:
- 版本1的Player类中
walking列表存储的是提前加载完成的Pygame Surface对象,传递给父类的paths参数本身就是Surface列表,Asset类直接取列表元素赋值给self.image,完全符合Pygame对Sprite对象image属性必须为Surface类型的要求。 - 版本2的Player类中
walking列表存储的是图片路径字符串,Asset类构造时仅将第一张路径加载为Surface赋值给初始的self.image,但self.images本身存储的还是未加载的路径字符串列表。
报错根源
报错触发在Sprite组调用draw()方法时,原因是代码中大概率存在帧动画切换逻辑:每帧更新self.images_index后,会执行self.image = self.images[self.images_index]完成帧切换。
版本2中self.images存储的是字符串,切换索引时直接将字符串赋值给了self.image,而Pygame的blits()方法要求传入的绘制源必须是Surface对象,字符串不符合类型要求,因此抛出TypeError: Source objects must be a surface错误。
注:Asset初始化时第一张图已经加载为Surface,所以初始化阶段不会报错,第一次切换动画帧时才会触发异常。
修复方案
如果要保留版本2的路径传递逻辑,只需要在Asset类的else分支中提前把所有路径加载为Surface再存入self.images即可:
else: # 批量加载所有路径为Surface self.images = [pygame.image.load(p).convert_alpha() for p in paths] self.images_index = 0 self.image = self.images[self.images_index]
内容的提问来源于stack exchange,提问作者Goamhobala
相关产品推荐
相关产品推荐

