2013-07-30 58 views
7

Tôi đã đọc các câu hỏi tương tự về vấn đề này trên Stack Overflow nhưng chúng đã không giúp ích gì. Đây là mã của tôi:pygame.key.get_pressed() không hoạt động

import pygame 
from pygame.locals import * 

pygame.init() 
screen = pygame.display.set_mode((640, 480)) 
pygame.display.set_caption('Hello World') 
pygame.mouse.set_visible(1) 

done = False 
clock = pygame.time.Clock() 

while not done: 
    clock.tick(60) 

    keyState = pygame.key.get_pressed() 

    if keyState[pygame.K_ESCAPE]: 
     print('\nGame Shuting Down!') 
     done = True 

Nhấn escape không thoát khỏi trò chơi hoặc in tin nhắn. Đây có phải là một lỗi? Nếu tôi in giá trị cho keyState [pygame.K_ESCAPE], nó luôn bằng 0.

Trả lời

12

Vấn đề là bạn không xử lý hàng đợi sự kiện của pygame. Bạn nên đơn giản gọi pygame.event.pump() ở phần cuối của vòng lặp của bạn và sau đó mã của bạn hoạt động tốt:

... 
while not done: 
    clock.tick(60) 

    keyState = pygame.key.get_pressed() 

    if keyState[pygame.K_ESCAPE]: 
     print('\nGame Shuting Down!') 
     done = True 
    pygame.event.pump() # process event queue 

Từ (tôi nhấn mạnh) docs:

pygame.event.pump()

xử lý nội bộ bộ xử lý sự kiện pygame

pump() -> None

Đối với mỗi khung của trò chơi, bạn sẽ cần thực hiện một số loại cuộc gọi đến hàng đợi sự kiện. Điều này đảm bảo chương trình của bạn có thể tương tác nội bộ với phần còn lại của hệ điều hành. Nếu bạn không sử dụng các chức năng sự kiện khác trong trò chơi của mình, bạn nên gọi pygame.event.pump() để cho phép pygame xử lý các tác vụ nội bộ.

Chức năng này không cần thiết nếu chương trình của bạn liên tục xử lý các sự kiện trên hàng đợi thông qua các hàm pygame.event khác.

Có những điều quan trọng phải được xử lý nội bộ trong hàng đợi sự kiện. Cửa sổ chính có thể cần được sơn lại hoặc trả lời hệ thống. Nếu bạn không thực hiện cuộc gọi đến hàng đợi sự kiện quá lâu, hệ thống có thể quyết định chương trình của bạn đã bị khóa.

Lưu ý rằng bạn không phải thực hiện việc này nếu bạn chỉ cần gọi pygame.event.get() ở bất cứ đâu trong vòng lặp chính của bạn; nếu không, bạn có thể gọi số pygame.event.clear() để hàng đợi sự kiện không được lấp đầy.

+0

Thực tế bạn chỉ cần gọi 'pygame.event.poll()' có thể nhanh hơn một chút. – martineau

1

Tôi có thể đề xuất sử dụng một chuỗi sự kiện thay thế không? Nó có thể là một ý tưởng tốt hơn:

while True: #game loop 
    for event in pygame.event.get(): #loop through all the current events, such as key presses. 
     if event.type == QUIT: 
      die() 

     elif event.type == KEYDOWN: 
      if event.key == K_ESCAPE: #it's better to have these as multiple statments in case you want to track more than one type of key press in the future. 
       pauseGame() 
+0

Tôi đã sử dụng phương pháp này trước nhưng nó không xử lý các lần nhấn phím đồng thời rất tốt. – ZeroDivide

+0

Bạn có thể đặt các giá trị Boolean thành các biến và làm cho chúng là True khi có 'keydown' và chúng làm cho chúng sai một lần nữa khi có một' keyup'. Sau đó, bạn chỉ cần kiểm tra xem các biến nào là đúng. Tôi sẽ chỉnh sửa câu trả lời của tôi với một ví dụ trong một giây –

+1

@ZeroDivide bạn có thể trộn và kết hợp, sử dụng các sự kiện và get_state tùy thuộc vào những phím nào nên sử dụng. – ninMonkey

0

làm điều gì đó như thế này:

import pygame 
from pygame.locals import * 

pygame.init() 
screen = pygame.display.set_mode((640, 480)) 
pygame.display.set_caption('Hello World') 
pygame.mouse.set_visible(1) 

done = False 
clock = pygame.time.Clock() 

while not done: 
    clock.tick(60) 
    for event in pygame.event.get(): 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 

    key = pygame.key.get_pressed() 

    if key[K_ESCAPE]: 
     print('\nGame Shuting Down!') 

    pygame.display.flip() 

bạn không cần pygame. trên nếu Statment và cũng có thể bạn nên gọi pygame.display.flip() nên nó đúng cách cho thấy cửa sổ sau đó bạn cần một vòng lặp sự kiện để thoát khỏi chương trình