簡體   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