Pygame中使用自定义属性更新矩形位置失败问题排查
问题:自定义Pygame矩形类xValue更新后,屏幕上的矩形位置未同步变化
我正在调试一段程序,尝试为自定义矩形类添加xValue属性以更新其位置。以下是我的代码:
import os ; os.environ['PYGAME_HIDE_SUPPORT_PROMPT']='False' import pygame, random pygame.init() display = pygame.display.set_mode((401, 401)) display.fill("white") ; pygame.display.flip() class MyRect(pygame.Rect): def __setattr__(self, attr, value): # Sets a custom attribute to a rectangle super().__setattr__(attr, value) if attr == 'xValue': pygame.Rect.move(self, (value-self.centerx), 0) # Move the rectangle according to the xValue def contains(self, coords): return self.collidepoint(coords) square = MyRect(175, 175, 50, 50) pygame.draw.rect(display, 'steelBlue', square) # Draw the rectangle to the screen square.xValue = 200 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() ; exit() elif event.type == pygame.MOUSEBUTTONDOWN: if square.contains(pygame.mouse.get_pos()): square.xValue = random.randint(0, display.get_width()) # Update the square.xValue property pygame.display.flip() # Update the screen
运行程序时,square的xValue属性确实在变化,但屏幕上矩形的位置并未更新。请问我遗漏了什么?
解决方案
你的代码有三个核心问题,逐个修正就能解决:
pygame.Rect.move()不修改原矩形move()方法会返回一个新的移动后的矩形实例,不会改变当前self的位置。要原地修改矩形位置,必须用move_ip()(ip代表in-place):self.move_ip((value - self.centerx), 0)未重绘背景与矩形
你只在程序启动时绘制了一次矩形,后续位置变化后,旧的矩形会留在屏幕上,新位置的矩形没被绘制。需要在每次循环中先填充背景清除旧图形,再绘制新位置的矩形。屏幕刷新时机错误
把pygame.display.flip()放在事件循环内部会导致不必要的频繁刷新,应该移到事件循环之外,确保每次逻辑处理完成后统一刷新屏幕。
修正后的完整代码:
import os ; os.environ['PYGAME_HIDE_SUPPORT_PROMPT']='False' import pygame, random pygame.init() display = pygame.display.set_mode((401, 401)) class MyRect(pygame.Rect): def __setattr__(self, attr, value): super().__setattr__(attr, value) if attr == 'xValue': # 使用move_ip原地修改矩形位置 self.move_ip((value - self.centerx), 0) def contains(self, coords): return self.collidepoint(coords) square = MyRect(175, 175, 50, 50) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() elif event.type == pygame.MOUSEBUTTONDOWN: if square.contains(pygame.mouse.get_pos()): square.xValue = random.randint(0, display.get_width()) # 重绘背景和当前位置的矩形 display.fill("white") pygame.draw.rect(display, 'steelBlue', square) # 统一刷新屏幕 pygame.display.flip()
额外提醒:自定义__setattr__时,注意不要误操作Pygame Rect的内置属性,不过你这里只针对xValue处理,不会有问题。
内容的提问来源于stack exchange,提问作者Markas M
相关产品推荐
相关产品推荐

