
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で質問しましょう!
似たような質問が見つかりました
- 物理学 写真の解説の赤枠部分についてですが、 なぜ、(-vk-1)と-が付くのかがわからないです。 解説の③ 1 2023/02/10 23:54
- 数学 以下の問題教えて頂きたいです。 波動方程式 (∂^2/∂t^2−v^2(∂^2/∂x^2))u(x, 1 2022/06/05 17:24
- Mac OS MacBook Airに外付けテンキー(有線)を接続しましたが、認識してくれません。 MacBook 2 2022/10/08 19:10
- 損害保険 自動車事故で、標識などなく 十字路で相手方が左方向から私が右方向から 出会い頭でぶつかりました。 相 6 2022/07/13 10:29
- アクセサリ・腕時計 腕時計に詳しい方ご回答お願いします。 1時間おきにピッと鳴る音を消したいのですが、消す方法はありませ 1 2022/06/10 23:13
- JavaScript vertical sliderをautoplayしたい 2 2022/08/25 14:47
- その他(ヘルスケア・フィットネス) この動作に名前を付けたい 2 2022/09/17 13:02
- 妊娠 胎動のたびに同じ部分がズキっと痛むのですが… 2 2023/02/16 20:15
- 事故 他人に安全を委ねる人多すぎやしませんか?なぜ他人に委ねるのですかね? 信号のない交差点を同じタイミン 6 2023/04/02 16:59
- ゴルフ 【ゴルフポジションの謎】右腕を何も持たずに左右にに肩を軸にぶらんぶらんと振ると、右腕は 2 2023/04/08 06:25
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
-
大麻の使用罪がなかった理由や法改正での変更点、他国との違いを弁護士が解説
ドイツで2024年4月に大麻が合法化され、その2ヶ月後にサッカーEURO2024が行われた。その際、ドイツ警察は大会運営における治安維持の一つの方針として「アルコールを飲んでいるグループと、大麻を吸っているグループ...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
VB.NETのUsingキーワードの使い方
-
<input type="file">タグで「キ...
-
ACCESS側からEXCELの書式を設定...
-
Excel VBA 実行中に一瞬フリー...
-
Excel VBA で処理中断(DoEvents...
-
Excel VBA 自動的に閉じるMsgBox
-
OnTimer()時にクリックされたこ...
-
エクセルVBAでクリップボード内...
-
スタティックテキストが表示さ...
-
SendMessage中のメッセージ・ル...
-
Application.ScreenUpdating=Fa...
-
VBA kernel32 の意味
-
beforecloseの中からの抜け出し方
-
メッセージボックスのボタン名変更
-
MFCのメニューバーのイベント取得
-
Macターミナルで実行中のプログ...
-
Excel VBAにて、2GB超の点群デ...
-
C# シリアル通信でデータ受信...
-
sendkeysにてALT+CTRL+INSERTを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
ACCESS側からEXCELの書式を設定...
-
メッセージボックスのボタン名変更
-
VBSで応答不要のメッセージボッ...
-
VBA kernel32 の意味
-
Excel VBA で処理中断(DoEvents...
-
VBA、UserFormを前面に出力して...
-
Application.ScreenUpdating=Fa...
-
MFCのワーカースレッドとUIスレ...
-
ASP.NETでのメッセージ画面を出...
-
「キャンセル」ボタン付きの処...
-
シャットダウン時のExcel強制終...
-
【C#】 あるイベントから別イ...
-
ボタンが押された事を検知する...
-
PostMessageの連続送信
-
VBA メッセージボックスを自動...
-
エクセルVBAでクリップボード内...
-
VCでウエイトをミリ秒でかけ...
-
ループを使わずに、特定時間に...
-
VB6 コマンドボタン クリック...
おすすめ情報