
No.4ベストアンサー
- 回答日時:
こんにちは。
ゲームの種類にもよるのですが、DirectX環境下と言う事で、秒間60回描写辺りを目安に作っているゲームなら、アイドリングループ位は持っているでしょうから、その中でGetKeyboardState()を呼び出して検出するのが手っ取り早いです。
ただ、ウィンドウのメッセージループ外では無効な上、ウィンドウがタスクバー化したり、フォーカスを失うと、一気に入力を受け付けなくなるので、DirectInputの使用が最も無難だと思います(何処でも現在の入力状態が受け取れる)。
初期化は面倒ですが、呼び出し方としてはGetKeyboardState()と大した変わりがありません(良く似ていると言う事です)。
+----------------------------------------------------------------+
BYTE key[256] = {0};
::GetKeyboardState(key);
//左後方大ジャンプ成立
if((key[VK_UP] & 0x80) && (key[VK_LEFT] & 0x80))
{
ココでキャラが左上に大ジャンプする
}
+----------------------------------------------------------------+
BYTE Key[256] = {0};
g_pKeyboard->GetDeviceState(256, Key);
//左後方大ジャンプ成立
if((key[DIK_UP] & 0x80) && (key[DIK_LEFT] & 0x80))
{
ココでキャラが左上に大ジャンプする
}
+----------------------------------------------------------------+
尚、キーボードの同時押しについては既出の通り、DirectInputを使用しても受け付けない組み合わせがあります。
DirectInputに関しては以下を参考にして見て下さい。
http://www.shader.jp/xoops/html/masafumi/directx …
http://oshiete1.goo.ne.jp/qa4345138.html
http://oshiete1.goo.ne.jp/qa4312916.html
No.3
- 回答日時:
蛇足ですが。
当方の回答の例では「キーボードイベントを受け取って、キーの状態により変数を操作する部分」と「キーの状態を持つ変数の値により、方向を認識する部分(つまり、移動の処理をする部分)」は「別々」にしてあります。
何故なら、ゲームの場合「自機(自分)は、一旦動き出したら一定速度で動く筈」であり、キーボードイベントが来た時しか動かないのは変です。
なので「キーボードイベントを処理する場所で、自機(自分)を移動させる処理をしてはいけない」のです。
自機(自分)を移動させる処理は、画面表示1回につき1回ごと(つまり、1フレームごと)に行わねばならず、キーボードイベントとは別のタイミングで行わねばなりません。
そのため、2つの処理を「別々」にしてあるのです。
No.2
- 回答日時:
WM_KEYDOWN、WM_KEYUPメッセージをキャプチャして下さい。
上下左右キーそれぞれについて、押下中かどうかの状態を持つ変数を1つ用意します。
そして、変数のビット0~3を、上下左右キーの状態に割り当てます。
WM_KEYDOWNイベントを受け取ったら、以下のようにします。
・WPARAMがVK_UPだったら変数のビット0を1にします。
・WPARAMがVK_DOWNだったら変数のビット1を1にします。
・WPARAMがVK_LEFTだったら変数のビット2を1にします。
・WPARAMがVK_RIGHTだったら変数のビット3を1にします。
WM_KEYUPイベントを受け取ったら、以下のようにします。
・WPARAMがVK_UPだったら変数のビット0を0にします。
・WPARAMがVK_DOWNだったら変数のビット1を0にします。
・WPARAMがVK_LEFTだったら変数のビット2を0にします。
・WPARAMがVK_RIGHTだったら変数のビット3を0にします。
具体的には、以下のようになります。
事前に変数KeyBitsを用意し0に初期化しておいて下さい。
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch ( msg )
{
case WM_KEYDOWN: // キーが押されたとき
switch ( wp )
{
case VK_UP:
KeyBits |= 1;
return 0;
case VK_DOWN:
KeyBits |= 2;
return 0;
case VK_LEFT:
KeyBits |= 4;
return 0;
case VK_RIGHT:
KeyBits |= 8;
return 0;
}
break; // 特に処理しないキーはDefWindowProc()に任せる
case WM_KEYUP: // キーが離されたとき
switch ( wp )
{
case VK_UP:
KeyBits &= ~1;
return 0;
case VK_DOWN:
KeyBits &= ~2;
return 0;
case VK_LEFT:
KeyBits &= ~4;
return 0;
case VK_RIGHT:
KeyBits &= ~8;
return 0;
}
break; // 特に処理しないキーはDefWindowProc()に任せる
case WM_DESTROY: // ウィンドウが破棄されるとき
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wp, lp );
}
で、変数KeyBitsの値により、以下のように場合分けします。
switch ( KeyBits )
{
case 0x01: ///↑を押している
case 0x0d: ///↑→←を押している
上方向の処理
break;
case 0x02: ///↓を押している
case 0x0e: ///↓→←を押している
下方向の処理
break;
case 0x04: ///←を押している
case 0x07: ///↑↓←を押している
左方向の処理
break;
case 0x08: ///→を押している
case 0x0b: ///↑↓→を押している
右方向の処理
break;
case 0x09: ///↑→を押している
右上方向の処理
break;
case 0x0a: ///↓→を押している
右下方向の処理
break;
case 0x05: ///↑←を押している
左上方向の処理
break;
case 0x06: ///↓←を押している
左下方向の処理
break;
case 0x00: //どれも押してない
case 0x03: //↑↓を押している
case 0x0c: //→←を押している
case 0x0f: //↑↓→←を押している
// 何もしない
break;
}
なお、ウィンドウ上でキーを押したままにして、マウスで別ウィンドウに移動して、別ウィンドウがアクティブになった状態でキーを離すと、元のウィンドウにはWM_KEYDOWNのみが送られ、WM_KEYUPが送られない場合があります。
つまり、矢印キーを押している最中に別ウィンドウに移ってから、元のウィンドウに戻ると「キーを押してないのに、矢印キーがいつまでも押しっぱなしの状態のまま」になる事があります。
なので「ウィンドウが非アクティブになった時」に「全部の矢印キーが離された事にする」と言う細工が必要です(前述の例で言えば、KeyBits変数を0にしてしまう)
また、キーのオートリピート機能により、WM_KEYDOWNイベントが連続で大量に発生する事があるので「WM_KEYDOWNが連続で発生しても大丈夫」な書き方をする必要があります。
No.1
- 回答日時:
キーボードの同時押しに関しましては、
GetKeyboardState()が使えると思いますので、
参照してみてください。
ただし、キーの組み合わせや、キーボードの種類によっては、
同時押しを正しく取得出来る保証はありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
VBA、UserFormを前面に出力して...
-
ACCESS側からEXCELの書式を設定...
-
VBA メッセージボックスを自動...
-
メッセージボックスのボタン名変更
-
C#で処理中画面を表示したい。
-
アクセスでのキー送信について
-
「キャンセル」ボタン付きの処...
-
VBA kernel32 の意味
-
VC++のシンボルブラウザについて
-
for文実行中を途中で中断するに...
-
beforecloseの中からの抜け出し方
-
PostMessageの連続送信
-
VB6 コマンドボタン クリック...
-
シャットダウン時のExcel強制終...
-
Macターミナルで実行中のプログ...
-
powershell を使いカレントディ...
-
TCP/IP通信時のサーバーからの受信
-
Windows上で、シグナル(SIGTERM...
-
プロセスIDの取得方法について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
ACCESS側からEXCELの書式を設定...
-
VBSで応答不要のメッセージボッ...
-
PostMessageの連続送信
-
エクセルVBAでクリップボード内...
-
VBA、UserFormを前面に出力して...
-
ファンクションキーのキャンセ...
-
Application.ScreenUpdating=Fa...
-
【MFC】イベントの無効化について
-
VBA kernel32 の意味
-
マウスのクリックを無視したい
-
ループを使わずに、特定時間に...
-
Excel VBA 自動的に閉じるMsgBox
-
「キャンセル」ボタン付きの処...
-
シャットダウン時のExcel強制終...
-
OSシャットダウン時の常駐アプ...
-
VB.NETで数秒間msgboxの...
-
VB6 コマンドボタン クリック...
-
Excel VBA 実行中に一瞬フリー...
おすすめ情報