Pygame制作游戏菜单报错:'pygame.Rect' object has no attribute 'pygame'
错误原因
抛出该错误的直接原因是你代码中if menu.pos.pygame.Rect.collidepoint(mouse_pos):这行的API调用语法完全错误:
- 你已经通过
menu.pos拿到了pygame.Rect类型的实例对象,不需要再重复加pygame.Rect前缀 - 该写法相当于尝试访问
Rect实例对象的pygame属性,而这个属性本身不存在,所以触发属性错误。
除此之外你的代码还存在3个会导致后续报错的逻辑问题:
- 菜单绘制方法调用拼写错误:你写的
menu.drow()应该是menu.draw() - 鼠标事件判断的缩进错误:当前
if event == pygame.MOUSEBUTTONDOWN写在了事件循环外面,此时event变量只能取到循环最后一个事件,且判断条件应该是event.type == pygame.MOUSEBUTTONDOWN - Menu类目前没有生成对应文字的Rect对象属性
pos,你只实现了文字渲染绘制逻辑,没有把文字表面转成Rect对象赋值给实例的pos属性。
解决方法
1. 修正Menu类逻辑
给Menu类补充初始化时生成文字Rect的逻辑:
class Menu: # 保留原有初始化参数,补充pos属性生成逻辑 def __init__(self, pos_x, pos_y, fs, text, color): self.pos_x = pos_x self.pos_y = pos_y self.fs = fs self.text = text self.color = color # 提前生成文字表面和对应的Rect对象 self.font = pygame.font.SysFont('fonts/crackman.ttf', self.fs) self.text_surf = self.font.render(self.text, False, self.color) self.pos = self.text_surf.get_rect(topleft=(pos_x, pos_y)) def draw(self): screen.blit(self.text_surf, self.pos)
2. 修正main函数的事件判断和碰撞检测逻辑
def main(): flag = True clock = pygame.time.Clock() menu = Menu(20, 70, 30, 'hello!', (255, 0, 0)) while flag: screen.fill(fill_color) # 每次循环重绘背景,避免文字拖影 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 鼠标事件判断放到事件循环内 if event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = event.pos # 直接调用Rect实例的collidepoint方法 if menu.pos.collidepoint(mouse_pos): # 这里补充点击菜单后的业务逻辑 print("菜单被点击") menu.draw() # 修正拼写错误 pygame.display.flip() # 刷新画面 clock.tick(60)
3. 碰撞检测语法说明
pygame.Rect实例直接调用collidepoint(坐标)方法即可判断坐标是否在矩形范围内,不需要加任何前缀,标准用法为:rect实例.collidepoint(x, y) 或者 rect实例.collidepoint((x,y))
内容的提问来源于stack exchange,提问作者GUFFYch
相关产品推荐
相关产品推荐

