グローバルキーボードの状態


7

キーボード入力の処理について次の考えがあります。次のように、「メイン」のゲームクラスで入力をキャプチャします。

protected override void Update(GameTime gameTime)
{
    this.CurrentKeyboardState = Keyboard.GetState();

    // main :Game class logic here

    base.Update(gameTime);

    this.PreviousKeyboardState = this.CurrentKeyboardState;
}

次に、キーボードの状態(internalスコープを持つ)を他のすべてのゲームコンポーネントで再利用します。この背後にある理由は、1)キーボード処理の負荷を最小限に抑え、2)同様のキーボード状態変数を使用して他のすべてのクラスの「汚染」を減らすことです。

私はゲーム開発とXNA開発の両方でまったくの初心者なので、これらすべてが妥当に聞こえるかどうか知りたいのですが。

UPDATE:誰かが興味を持っている場合によって示唆されているように、実際のユーティリティクラス、デビッドGouveiaの、私が作成したここで見つけることができます

回答:


12

はい、それは完全に合理的です、そして私はそれでそれを残すことができました!

...でも個人的にはもう少しカプセル化する方が好きです。したがって、内部の状態を管理する代わりにGameクラスそれにグローバルアクセスを提供する代わりに、それを独自のクラスにラップすることを好みます。

メモリからの例です。詳細を逃したかどうかはわかりませんが、重要なのは一般的な考え方です。

public static class InputManager
{
    public static void Update()
    {
        _previousKeyboardState = _currentKeyboardState;
        _currentKeyboardState = Keyboard.GetState();
    }

    public static bool IsKeyDown(Keys key) 
    {
        return _currentKeyboardState.IsKeyDown(key);
    }

    public static bool IsKeyUp(Keys key)
    {
        return _currentKeyboardState.IsKeyUp(key);
    }

    public static bool OnKeyDown(Keys key)
    {
        return _currentKeyboardState.IsKeyDown(key) && _previousKeyboardState.IsKeyUp(key);
    }

    public static bool OnKeyUp(Keys key)
    {
        return _currentKeyboardState.IsKeyUp(key) && _previousKeyboardState.IsKeyDown(key);
    }

    private static KeyboardState _currentKeyboardState;
    private static KeyboardState _previousKeyboardState;
}

次にGame.Update、マネージャーのUpdateを呼び出すだけです。

InputManager.Update();

そして最後に、ゲームの他のすべての場所でラッパーを直接使用できます。

if(InputManager.OnKeyDown(Keys.Space))
{
    // Shoot once
}

いくつかの利点:

  • ソリューションと同様に、現在と以前のキーボードの状態を管理する必要があるのは、アプリケーション内の1箇所だけです。
  • ただし、キーボード処理でゲームクラスを汚染するのではなく、そのために独自のクラスにカプセル化されます。
  • クラスは静的であるため、グローバルにアクセスできます。したがって、必要ない場合は、ゲームクラスへのグローバルアクセスを提供する必要はありません。
  • また、再利用も簡単です。新しいプロジェクトを開始する場合は、そのクラスをドロップするだけで十分です。

その間、APIを簡単に記録および再生できます。このようにして、後でテスト目的で缶詰入力を使用できます。
Patrick Hughes

@PatrickHughesコメントについて少し詳しく説明していただけますか?これにはどのようなアプローチを取ることができますか?いくつかのリンクは役に立つかもしれません。
Petr Abdulin

2
@PetrAbdulin KeyboardStateタイムスタンプに関連付けられたオブジェクトのリストを構造体に保持する必要があります。テストのためにゲームをプレイするときに、gameTime.TotalGameTime各フレームを取得し、それをstructに入れ_currentKeyboardState、ゲーム終了時にKeyboardStatesとTimeSpan.Milliseconds intsのリストをディスクに書き込みます。その後、あなたは、テスト入力モードでゲームを実行したときに読むKeyboardStateのをしてintね、このファイルから、次のことをリストのチェックからそれらを読んでKeyboardStateの関連するタイムスタンプが現在の一致するgameTime.TotalGameTime.Millisecondsプロパティを。
michael.bartnett 2012

@ michael.bartnett詳しい説明ありがとうございます。これはすべて理にかなっています。
Petr Abdulin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.