Pygame调用spritecollide检测精灵边界碰撞报AttributeError求解
报错原因
报错AttributeError: 'int' object has no attribute 'rect'来自两个核心错误:
pygame.sprite.spritecollide的第二个参数必须传入pygame.sprite.Group类型的精灵组,你传入的border_bottom是一个存储4个整数的元组(0,955,1500,10),函数遍历元组时拿到的是单个int值,自然访问不到rect属性。- 你选错了碰撞检测方法:边界是普通矩形不是精灵组,不需要用spritecollide接口,直接用矩形碰撞检测方法即可。另外你当前只传入了单个evil精灵做检测,剩下20个邪恶饼干都没有覆盖碰撞逻辑,也无法实现全部饼干上下弹跳的效果。
修复方案
1. 统一边界对象类型
把border_bottom从元组改成和border_top一致的pygame.Rect对象:
# 原错误写法 # border_bottom = (0,955,1500,10) # 修正后 border_bottom = pygame.Rect(0,955,1500,10)
2. 重写碰撞检测逻辑
用矩形碰撞方法colliderect实现精灵和边界的检测,同时遍历所有邪恶饼干,独立控制每个饼干的运动方向:
def collisioncookie(cookie_group, top_border, bottom_border): for cookie in cookie_group: # 碰到底部边界,速度反向向上 if cookie.rect.colliderect(bottom_border): cookie.y_speed = -2 # 碰到顶部边界,速度反向向下 if cookie.rect.colliderect(top_border): cookie.y_speed = 2 # 按当前速度更新垂直位置 cookie.rect.y += cookie.y_speed
3. 调整EvilCookie类逻辑
去掉类里错误的全局变量声明、无效绘制代码,给每个饼干实例加独立的垂直速度属性,避免全局变量导致所有饼干运动状态同步异常:
class EvilCookie(pygame.sprite.Sprite): def __init__(self,picture_path,pos_x,pos_y): super().__init__() self.image = pygame.image.load(picture_path).convert_alpha() self.rect = self.image.get_rect() self.rect.center = [pos_x,pos_y] self.y_speed = 1 # 初始向下运动,速度为1 # 原类里的update、topcollide、bottomcollide方法可全部删除,位置更新统一在碰撞函数中处理
4. 修正主循环调用
把原来只检测单个evil的调用,替换为检测整个邪恶饼干组:
# 原错误调用 # collisioncookie(evil) # 修正后 collisioncookie(evil_cookies, border_top, border_bottom)
同时把主循环里evil_cookies.update()这行删掉,避免重复移动饼干导致速度异常。
其他待修复的隐性bug
- EvilCookie初始化里的
pygame.draw.rect(screen,(255,255,255),self)写法错误,pygame.draw.rect第三个参数需要传入Rect对象,self是精灵实例,运行到这行也会触发报错,直接删除即可,边界矩形你已经在主循环里统一绘制了。 - Player类的move方法存在重复位移逻辑:同时修改topleft属性又调用move_ip会导致移动速度加倍,简化为如下写法即可:
def move(self, x_speed, y_speed): self.rect.move_ip(x_speed, y_speed) - 事件循环内部的
player.move(int(origin_x),int(origin_y))调用多余,会导致单次帧内多次触发移动,直接删除这行,保留事件循环外的move调用即可。
内容的提问来源于stack exchange,提问作者Reincracy
相关产品推荐
相关产品推荐

