为何pygame.key.get_pressed()在while循环外无法正常工作?
问题
我写了一段简单的Pygame代码,功能是显示一个矩形,按下键盘'a'键时矩形边框宽度增加1。代码在while循环内调用pygame.key.get_pressed()时能正常运行,但把keys = pygame.key.get_pressed()声明在while循环外后,按下'a'键就无法被识别了。
正常运行的代码
import pygame, sys def main(): pygame.init() DISPLAY=pygame.display.set_mode((500,400),0,32) pygame.display.set_caption('hello world') WHITE=(255,255,255) BLUE=(0,0,255) rectWidth = 1 while True: DISPLAY.fill(WHITE) pygame.draw.rect(DISPLAY,BLUE,(100,100,100,50), rectWidth) keys = pygame.key.get_pressed() if keys[pygame.K_a]: rectWidth += 1 for event in pygame.event.get(): if event.type==pygame.QUIT: pygame.quit() pygame.display.update() pygame.time.delay(20) main()
修改后失效的代码片段
keys = pygame.key.get_pressed() while True: DISPLAY.fill(WHITE) pygame.draw.rect(DISPLAY,BLUE,(100,100,100,50), rectWidth) if keys[pygame.K_a]: rectWidth += 1
我查过关于get_pressed()失效的其他问题,但没找到匹配场景;也尝试找get_pressed()的源码但没找到。想知道:
- 为什么把keys声明在while循环外会导致'a'键无法被识别?
- 如何查看该函数的源码?
回答
1. 循环外声明keys失效的原因
pygame.key.get_pressed()的作用是获取当前时刻键盘所有按键的状态快照。如果把它放在while循环外面,只会在程序启动时执行一次,得到的是程序刚启动时的按键状态(此时'a'键肯定是未按下的)。而while循环是程序的主循环,每一轮循环都需要实时获取最新的按键状态,才能检测到用户后续按下'a'的操作。
放在循环内时,每一轮循环都会重新调用get_pressed(),拿到当前最新的按键状态,所以能正确识别'a'键的按下动作。
另外要注意,Pygame的事件队列需要被正常处理(也就是代码里的for event in pygame.event.get()循环),否则按键状态可能无法及时更新——不过你这里的问题核心还是get_pressed()只执行了一次,没有实时更新状态。
2. 查看get_pressed()源码的方法
Pygame核心功能基于C语言实现,Python层是封装代码,你可以通过两种方式查看:
- 查看Python封装层代码:如果是用pip安装的pygame,找到Python安装目录下的
Lib/site-packages/pygame/key.py文件,里面能看到get_pressed()的Python封装逻辑,不过它最终会调用底层的C函数。 - 查看C核心源码:Pygame的C核心代码托管在代码仓库中,找到
src_c/pygame目录下的key.c文件,其中PyKey_GetPressed函数就是get_pressed()对应的底层实现,负责从系统获取按键状态并返回给Python层。
内容的提问来源于stack exchange,提问作者moortje
相关产品推荐
相关产品推荐

