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を探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
VBSで応答不要のメッセージボッ...
-
VBA kernel32 の意味
-
HTA(HTMLアプリケーション)にて...
-
VBA、UserFormを前面に出力して...
-
”お待ち下さい”が表示できない。
-
ACCESS側からEXCELの書式を設定...
-
vb.netでバッチ処理
-
ASP.NETでのメッセージ画面を出...
-
OSでの動作スピードの違い
-
VB.NETで数秒間msgboxの...
-
エクセルが勝手に立ち上がる
-
【C#】 あるイベントから別イ...
-
WEB上にボタンが押せない
-
DoEvents
-
VB Loopを一時停止し再開あるい...
-
エクセルVBAでクリップボード内...
-
シャットダウン時のExcel強制終...
-
Application.ScreenUpdating=Fa...
-
VBA メッセージボックスを自動...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
ACCESS側からEXCELの書式を設定...
-
VBA メッセージボックスを自動...
-
VBA kernel32 の意味
-
Application.ScreenUpdating=Fa...
-
VBA、UserFormを前面に出力して...
-
Excel VBA で処理中断(DoEvents...
-
エクセルVBAでクリップボード内...
-
VBSで応答不要のメッセージボッ...
-
Excel VBA 自動的に閉じるMsgBox
-
VCでウエイトをミリ秒でかけ...
-
キーボード入力、マウス操作を...
-
C#で処理中画面を表示したい。
-
【C#】 あるイベントから別イ...
-
マウスのクリックを無視したい
-
【MFC】イベントの無効化について
-
Excelのワークシートに行を挿入...
-
アクセスでのキー送信について
-
シャットダウン時のExcel強制終...
おすすめ情報