为什么pygame.key.get_pressed没有按预期工作?

时间:2015-11-01 19:44:30

标签: python python-3.x pygame

使用Python 3和Pygame,我的Mac OSX(10.11.1)上的pygame.key.get_pressed()函数似乎没有按预期工作。

导入pygametime模块后,我使用简单的pygame.K_w检查是否按下了 w 键(if) - 声明和Pygames pygame.key.get_pressed()函数。

但测试失败并且It didn't work打印时间非常短暂:

#!/usr/bin/env python3
import pygame, time
pygame.init()

while True:
    keypressed = pygame.key.get_pressed()

    time.sleep(5)
    print("5 seconds later")

    if keypressed[pygame.K_w]:
         print("it worked")
    else: 
         print("It didn't work")

2 个答案:

答案 0 :(得分:4)

第一个问题是你实际上并没有创建一个Pygame窗口使用pygame.display.set_mode()功能初始化窗口或屏幕进行显示。通常这是在Pygame程序中调用主事件循环之前完成的:

import pygame
pygame.init()

#initialize a display with 100 x 100 pix resolution  
display = pygame.display.set_mode((100,100))

while True:
    #some code

因为您没有在主游戏循环中使用任何事件功能, Pygame无法处理内部操作,例如关键状态信息信息。要避免这种,您应该在事件循环中调用pygame.event.pump()

while True:
    #internally process pygame event handlers
    pygame.event.pump()
    keypressed = pygame.key.get_pressed()

    time.sleep(5)
    print("5 seconds later")

    if keypressed[pygame.K_w]:
        print("it worked")
    else: 
        print("It didn't work")

现在你的程序应该识别pygame.K_w关键动作,但是自从你使用Pythons time.sleep()函数进入游戏后每5秒钟就会识别一次。

因为这不是一个好的做法,所以有许多解决方案可以避免这个问题。你可以:

  • 调用而不是pygame.event.pump()函数pygame.event.wait()等待事件并在没有事件发生时让游戏休眠:

    import pygame
    pygame.init()
    
    display = pygame.display.set_mode((100,100))
    
    while True:
        #wait for a single event from the queue
        pygame.event.wait()
        keypressed = pygame.key.get_pressed()
    
        if keypressed[pygame.K_w]:
            print("it worked")
        else: 
            print("It didn't work")
    
  • 使用pygame.time.Clock对象为您的程序设置帧率

    import pygame
    pygame.init()
    
    display = pygame.display.set_mode((100,100))
    
    clock = pygame.time.Clock()
    
    while True:
        pygame.event.pump()
        keypressed = pygame.key.get_pressed()
    
        if keypressed[pygame.K_w]:
            print("it worked")
        else: 
            print("It didn't work")
    
        #compute how many milliseconds have passed since the previous call
        clock.tick(30)
    

答案 1 :(得分:1)

首先,你应该初始化你的pygame窗口,然后调用你的函数来处理你所有的事件(比如等待一个键被按下并在那之后做出反应)。

import pygame
pygame.init()
screensize = (100, 100) #choose the size, in pixels.
window = pygame.display.set_mode(screensize) #Initialize your pygame window!
gameloop()

您的游戏循环功能如下:

while not finished:
    finished = doStuff() #returns True if the game should end.
pygame.quit()

变量'finished'应该让程序知道它应该何时结束,例如,在按下窗口右上角的'X'之后。 在这个函数中,我们将监听所有事件,例如按下一个键,释放它,按住它等等。

def doStuff():
    events = pygame.event.get() #Use this function to get all the events that happened, then iterate through it.
    finished = False
    for event in events:
        if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
            print("It worked!")
        if event.type == pygame.QUIT:
            final = True
        else:
            print("It didn't work")
        #more events here
    return finished