16

C++ DirectX 2D ゲームに取り組んでおり、キーボードとマウスの入力が必要です。
ウィキペディアは次のように述べています。

Microsoft は、新しいアプリケーションが DirectInput の代わりにキーボードとマウスの入力に Windows メッセージ ループを利用することを推奨します。

では、どのように使用すればよいですか?
描画と更新 (ゲーム ロジック) を処理する GameScreen クラスがあり、Windows メッセージ ループ内で Draw メソッドと Update メソッドを呼び出します。

ありがとう

4

7 に答える 7

14

ウィンドウを表示するにはメッセージ ポンプを実行する必要があるため、そのポンプを使用してキーボードとマウスの入力を処理することもできます。キーボードイベントを子ウィンドウに渡すかどうかは、完全にポンプ次第です。必要に応じて、ポンプでそれらを処理できます。

典型的なメッセージ ポンプは次のようになります。

while (GetMessage(&msg, NULL, 0, 0))
{
    if (WM_QUIT == msg.message)
       break;
    TranslateMessage(&msg); // post a WM_CHAR message if this is a WM_KEYDOWN
    DispatchMessage(&msg);  // this sends messages to the msg.hwnd
}

ゲームの場合、ポンプは次のようになります

while (true)
{
   if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD))
   {
      bool fHandled = false;
      if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
         fHandled = MyHandleMouseEvent(&msg);
      else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
         fHandled = MyHandleKeyEvent(&msg);
      else if (WM_QUIT == msg.message)
         break;

      if ( ! fHandled)
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
   }
   else
   {
       // if there are no more messages to handle right now, do some
       // game slice processing.
       //
   }
}

もちろん、実際のポンプはそれよりもさらに複雑になる可能性がMsgWaitForMultipleObjectsあり、処理するメッセージがない場合でも定期的に目を覚ますことができますが、メッセージがある場合はすぐに目を覚ますことができます。

于 2010-01-30T00:56:30.303 に答える
7

DirectInput は正当な理由で廃止されました。私の知る限り、それは余分なスレッドを作成し、Windows のRaw Inputインターフェイスを照会するだけです。最高のパフォーマンスを得るには、Raw Input を直接使用します。

パフォーマンスが問題にならない場合 (現在のハードウェアでの 2D ゲームの場合はそうだと思います)、Microsoft のアドバイスに従い、John Knoeller の説明に従ってウィンドウ メッセージを使用してください。

于 2010-01-30T13:53:32.953 に答える
3

参考までに: Re John Knoeller's answer ... 単純化されたメッセージ ポンプは次のようになります。

while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

彼が含めた WM_QUIT テストは、WM_QUIT が受信されたときに GetMessage がゼロを返すため、真になることは決してありません。ただし、メッセージが返されたかどうかにかかわらず、PeekMessage は true/false を返すため、PeekMessage ループで WM_QUIT をテストする必要があります。GetMessage はメッセージが返されるまでブロックするため、異なる戻り値を持つことができます。

于 2010-02-18T13:57:33.793 に答える
1

ゲームに単一のウィンドウがある場合、私が知る限り、区別は純粋に好みの問題です. ただし、複数のウィンドウを使用している (または使用を計画している、または将来的に使用する可能性を完全に除外できない) 場合、ウィンドウのメッセージングは​​面倒になる可能性があります。

問題は、デフォルトでキーボード/マウス メッセージが現在フォーカスのあるウィンドウにのみルーティングされることです。通常、ゲームではフォーカスを (ハイスコア ビュー、レーダー ビュー上の敵などに) 切り替えて、インタラクティブ性を維持できるようにする必要があります。 . 簡単な解決策は、直接クエリを実行するためにキーボード/マウス入力を必要とし、メッセージ転送に依存しないすべてのモジュール、つまり DirectInput です。

もちろん、あなたの特定のシナリオについてはあまり言えません-私の2cだけです。

于 2010-01-29T21:30:40.853 に答える
1

はい、MSDN の投稿は正しいです。Windowsメッセージを使用すると、多言語サポート(ユーザーが使用しているあらゆる種類のキーボード)/ユーザーの個人設定(マウスの左ボタンではなく右ボタン)などを使用できます.DirectInput / XInputを使用するには破棄する必要があります. ゲームパッド/ジョイスティックのサポートには、これら 2 つだけを使用してください。残りについては、Windows メッセージを使用してください。

詳細については、John Knoeller の回答に同意します。

于 2010-01-30T13:37:22.070 に答える
0

特殊な状況下でのみ直接入力を使用する

getmessage で使用される Windows メッセージ ループの良い点は、CPU 使用率が 0% であることです。ユーザーからのキーを待つ、データベースや税務プログラム、さらにはワード プロセッサなどでユーザーからデータを収集するなど、非プロセッサ集約的な処理を行っている場合は、getmessage で Windows メッセージを使用するだけでも意味があります。上記のすべてのプログラムの日付は、ユーザーがキーを押したときのプロセスです。

Windows メッセージ ループがキーを処理するために必要なのは、そのプログラムを切り替えることだけです。マウスがウィンドウ内にある必要さえありません。

特殊事情用直接入力

必要な場合: 1) キーがいつ押されて離されるかを知る。また、キー押下として検出されたキーの繰り返しを望まない場合もあります。
2) 別のプログラムに切り替えられたときにバックグラウンドでキーを処理します。

上記のいずれかに該当する場合は、直接入力を使用してください。

ユーザーからデータを収集するだけの場合は、sleep コマンドを使用してプログラムの実行を一時停止する必要があります。プログラムがユーザーからのキーを待っているだけの場合は、タスクマネージャーでプログラムの CPU 使用率を 0% にする必要があります。

キーの直接入力をポーリングするまでプログラムをスリープ状態にするスリープ機能を使用します。

したがって、ご覧のとおり、ユーザーからキーを収集するという単純な通常のタスクを実行している場合、直接入力はプログラミング時間を無駄にします。

于 2015-08-27T07:01:10.027 に答える
-1

XInput は間違いなく進むべき道です。低遅延入力はゲームにとって重要であり、XInput (新しい DirectXSDK の DirectInput の置き換え) はまさにこれらのユースケース向けに設計されています。

さらに、すぐにゲームコントローラー、ジョイスティックなどをサポートできます。

于 2010-01-29T22:15:17.010 に答える