繁体   English   中英

为什么我的暂停系统不起作用? (Pygame)

[英]Why is my pause system not working? (Pygame)

这是我的check_for_pause()函数:

#Check if the user is trying to pause the game
def check_for_pause():
   keys=pygame.key.get_pressed() #Get status of all keys
   if keys[K_SPACE]: #The space bar is held down
       global paused #Make global so it can be edited
       if paused==True: #It was paused, so unpause it
           paused=False
       elif paused==False: #It was playing, so pause it
           paused=True

        #Don't let the main loop continue until the space bar has been released again, otherwise the variable will flicker between True and False where the loop runs so fast!
        space_bar_pressed=keys[K_SPACE]
        while space_bar_pressed: #Repeat this loop until space_bar_pressed is False
           keys=pygame.key.get_pressed()
           if not keys[K_SPACE]: #Space bar has been released so set space_bar_pressed to False
              space_bar_pressed=False

但是,这会使我的程序在每次尝试暂停时都变得无响应! 基本上,我希望变量“ paused”为True或False。 按下空格键时,它应该更改为当前未选择的任何一个。 因为我在另一个永无休止的循环中使用了check_for_pause(),所以我需要这样做,以便函数仅在释放空格键时才停止执行,否则,如果用户按住空格键超过一秒钟,它将保持在正确与错误之间切换。

有什么想法为什么我在运行该程序时我的程序无响应? 我知道这与等待释放空格键的位有关,因为当我删除那部分代码时,我的程序可以正常运行(但是显然,暂停功能不起作用)。

您的主循环可能看起来像这样...

while True:
    check_for_pause()
    # Update the game
    # Draw the game

当您检查暂停时,并按下空格键时,暂停将设置为True。 然后,你有这个循环...

space_bar_pressed=keys[K_SPACE]
while space_bar_pressed: #Repeat this loop until space_bar_pressed is False
   keys=pygame.key.get_pressed()
   if not keys[K_SPACE]: #Space bar has been released so set space_bar_pressed to False
      space_bar_pressed=False

此循环的问题是,您假设pygame.key.get_pressed()将继续返回最新信息。 但是,查看pygame源代码 ,似乎它使用了SDL_GetKeyState,这是其文档的一部分。

Note: Use SDL_PumpEvents to update the state array.

换句话说,如果您不另外调用pygame.event.pump()类的东西,而反复调用pygame.key.get_pressed()不会给您更新的键状态,实际上会使用新的键状态来更新pygame。 因此,您可以通过将该泵功能引入循环中来快速解决此问题,因为当前它一直在运行。

话虽这么说:不要这样做。 如果以这种方式进行操作,则游戏在暂停时将无法执行任何操作:这包括显示“已暂停”屏幕,继续在后台播放音乐等。您要做的就是跟踪是否游戏暂停,如果暂停,请更改游戏的更新方式。

在游戏中更新内容的部分中,某些项目仅应在游戏暂停后才发生。 就像是...

paused = False
while True:
    # This function should just return True or False, not have a loop inside of it.
    paused = check_for_paused()

    if not paused:
        # This function moves your enemies, do physics, etc.
        update_game()

    draw_game()

在这种情况下,主循环仍然会发生,游戏将继续进行绘制,并且输入将继续得到处理。 但是,敌人和玩家不会移动,因此可以说游戏已“暂停”。

最后,还有一个事实就是您依赖于get_key_pressed(),而您可能不想这样做。 请参阅我给出的其他类似答案,以了解为什么应改为使用事件队列的原因。

即使暂停,也永远都不要停止运行游戏循环。 暂停通常也通过事件来处理。 例如看下面的代码:

import pygame, sys
from pygame.locals import *
pygame.init()
pygame.display.set_mode((400,400))

paused = False # global

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_SPACE:
                paused = not paused

    if paused:
        continue # skip this iteration if paused

    # add your game code here
    print 'game code running'

在上面的代码中,每当我按下空格键时,我会切换为暂停。 如果只想在按住空格键时暂停,请执行以下操作:

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type in (KEYDOWN, KEYUP): # checks membership in tuple
            if event.key == K_SPACE:
                paused = not paused

    if paused:
        continue # skip this iteration if paused

    # add your game code here
    print 'game code running'

作为一般说明,您应该始终在处理事件队列中的事件,否则Pygame只会哭泣和抱怨,什么也不做(无响应)。 因此,即使您暂停了游戏,也请不要停止游戏循环。

编辑:或者,正如abarnert在评论中指出的那样,您可以通过相等比较来做一个技巧,以确保您不会在KEYDOWN和KEYUP事件之间发生冲突:

paused = event.type == KEYDOWN

这样,您就不会遇到“同步问题”,只要您真正释放空格键,代码就不会意外将paused设置为True。 如果连续发生2个KEYDOWN事件或连续发生2个KEYUP事件(而不是像KEYDOWN,KEYUP,KEYDOWN,KEYUP等这样的平滑交替序列),则会发生这种情况。 最好不要假设所有事件队列都提供100%准确的事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM