为什么pygame.event.get()每帧只能调用一次

时间:2017-03-19 14:54:30

标签: python function python-3.x methods pygame

我正在编写一个函数,以便在不使用通常使用的for循环的情况下轻松检测按键操作:

for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == key:

我发现我编写的函数不起作用,这是因为我在所有运行每一帧的项目中都有test_for_quit函数。我发现这很有用,因为我可以把它复制到我正在写的任何程序中:

def test_for_quit():
    '''Shuts down the game if it's closed'''
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

令人惊讶的是,这是我自从我的所有程序实现该功能以来所做的第一个游戏,它不使用按键。但是我发现我写的新函数不起作用的原因是因为pygame.event.get()函数已经调用了test_for_quit

经过一些测试后,我发现这个方法不能被调用两次,例如:

while True:
    print(pygame.event.get())
    print() #Leaves an empty line
    print(pygame.event.get())

返回:

[<Event(17-VideoExpose {})>, <Event(16-VideoResize {'h': 600, 'size': (800, 600), 'w': 800})>, <Event(1-ActiveEvent {'gain': 0, 'state': 1})>, <Event(4-MouseMotion {'rel': (538, 315), 'pos': (537, 314), 'buttons': (0, 0, 0)})>]

[]

那么为什么pygame.event.get()只能被调用一次,这真的让我很感兴趣,我在互联网上找不到任何关于它的东西?

此外,我决定不继续使用test_for_quit函数和key_down函数,而只使用传统的for循环。

1 个答案:

答案 0 :(得分:3)

可以根据需要多次调用

event.get。问题是它确实将事件从事件队列中取出 - 并由您的程序来使用它们。当没有间隔第二次调用它时(pygame本身对&#34;帧&#34; - 在帧之间给出延迟)一无所知 - 所有事件都消失了,没有其他事件被生成。

event.get的文档内容为:

这将获取所有消息并将其从队列中删除。如果给出了类型或类型的序列,则只会从队列中删除这些消息。

If you are only taking specific events from the queue, be aware that the queue could eventually fill up with the events you are not interested.

您有两种选择:保持&#34;复制和粘贴&#34;调用event.get并通过使用其他调用来读取键盘状态 - pygame.key.get_pressed - 或者使用更智能的方式来消耗队列中的事件。

甚至还有一些方法可以检查事件队列中的evetns而不消耗它们 - 因此您可以在调用events.get之前拨打这些电话。

一个是函数本身允许你指定你感兴趣的事件类型。所以让我们假设你有一个处理鼠标事件的函数和一个处理keybard事件的函数:

def do_keys():
    for event in pygame.event.get(KEYDOWN):
         ...

def do_mouse():
    for event in pygame.event.get((MOUSEMOTION, MOUSEBUTTONDOWN)):
        ..
def main():
    while True:
        do_keys()
        do_mouse()
        # discard other events:
        pygame.event.get()
        # draw secreen
        ...
        pygame.time.delay(...)

或者,更简单的是,您可以简单地将调用的返回值分配给pygame.event.get到变量 - 这将是一个列表,您可以根据需要迭代多次。

events = pygame.event.get()
for event in events():
    # treat some evetns here
# some other logic here
...
do_keyboard_things(events)

def do_keyboard_things(events):
    for event in events:
         ...