HOWTO · Pygame

Pygame でキーボード入力を取得する方法

この記事では、Pygame でキーボード入力を取得する方法について説明します。 キーボード入力を取得するには、イベント ループと pygame.key.get_pressed() を使用する 2つの方法があります。

このページの内容

ゲームのニーズに基づいて入力処理を選んでください。キーが押されたときに一度だけ反応するには KEYDOWN イベントを使い、現在のフレームでどのキーが押されているかを確認するには pygame.key.get_pressed() を呼び出します。以下の例では、完全なウィンドウループの中で両方のアプローチを示します。

event ループを使って Pygame でキーボード入力を取得する

Pygame は、プログラムのために入力イベントとウィンドウイベントをキューに入れます。各フレームで pygame.event.get() を反復し、各イベントの type を確認してください。KEYDOWN イベントは押下を示し、その key フィールドが pygame.K_e のようなキーを識別します。KEYUP は解放を示します。ウィンドウがシステムイベントも処理し続けられるよう、これらのイベントをループ内で処理してください。

押下イベントは、メニューを開く、1 回発射するといったアクションに役立ちます。キーを押し続けても、その 1 回の KEYDOWN イベントが継続的な押下状態の確認に変わることはありません。継続的なアクションについては、次のセクションで示すように現在の状態をポーリングしてください。短いイベントとポーリングのパターンはアプリケーションの一部であり、完全なウィンドウではありません。ウィンドウの設定については、最小限の Pygame フレームワークで別途説明しています。

pygame.key.get_pressed() を使って Pygame でキーボード入力を取得する

pygame.key.get_pressed() はフレームごとに 1 回呼び出してください。キーボードの現在の状態を表すシーケンスのようなオブジェクトを返します。たとえば keys[pygame.K_w] のように、Pygame のキー定数でインデックスを指定します。その値が真の場合、そのキーは現在押されているため、ゲームはフレームごとに移動を更新できます。この関数は押下イベントではなく状態を報告します。ポーリングの間に始まって終わる非常に短い押下は観測されないことがあるため、すべての押下と解放が重要な場合はイベントキューを使ってください。

以下の例は両方の手法を組み合わせています。E の押下や解放はイベントキューで処理し、W は現在のキー状態で確認します。640×480 のウィンドウを開き、1 フレームだけ実行するため、ウィンドウを手動で閉じる必要なく起動できます。開いたままにするゲームでは、フレームの上限を while running に変更し、イベント処理、画面の更新、フレームレート制御をそのループ内に保持してください。Pygame とグラフィカルディスプレイが必要です。

この例を実行します。

import os

os.environ.setdefault("PYGAME_HIDE_SUPPORT_PROMPT", "1")
os.environ.setdefault("SDL_VIDEODRIVER", "dummy")

import pygame

pygame.display.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
running = True
frames = 0

while running and frames < 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_e:
            print("E Pressed")
        elif event.type == pygame.KEYUP and event.key == pygame.K_e:
            print("E Released")

    keys = pygame.key.get_pressed()
    if keys[pygame.K_w]:
        print("W is held")

    screen.fill((20, 20, 20))
    pygame.display.flip()
    clock.tick(60)
    frames += 1

pygame.quit()
print("Loop completed.")
Loop completed.