はじめまして、
キャラクタをカーソルキーで動かすプログラムを作りたいのですが
斜め移動の判定がうまくできずに困っています。
一応ななめには動くことは動くのですが
たとえば、上と右を同時におして(つまり右斜め上)にキャラが移動中に
上だけを離すと、キャラがとまってしまいます。
環境はVC++ToolkitとCoreSDKです。
ソースを下記に保存いたしましたので、どなたかご教授おねがいいたします。
Yahooブリーフケース (source.zip)
http://briefcase.yahoo.co.jp/
ID: programing_00
password: aaabbb
WM_KEYDOWNで、GetKeybordState()を使ってアローキーの状態をチェックすればOKかと。
DirectInput使ってもいいけど、こっちのが手軽でしょう。
あ、ダメでした。
いきなり同時押しした場合、止まりますね。
WM_KEYDOWNではダメなようですので、Timerイベント等、ある間隔でGetKeybordState()
を使い、キー状態を取得すれば一応はOKですね。
SunPac様、dairygoods様。ご返信ありがとうございます。
調べてみましたところ、
{
GetKeyState()はリアルタイムでキーボードを監視するわけではありません
これはメッセージ生成時までの状態を表しているのです
例えば処理中にキーが開放されたことについては、興味を示しません
http://black.sakura.ne.jp/~third/system/winapi/win.html
*Win32 API入門「仮想キーの状態」
}
とあったので、ご教授のようにキーボードの状態取得を随時おこなわなければならないようです
そこで,SunPac様にお教えいただきましたGetKeybordState()を組み込みましたが
コンパイル時に、
error LNK2019:unresolved external symbol _GetKeybordState・・・
と表示されてしまいます。
MSDNで参照してみましたが残念ながら見つからなかったです
再度、ご支援をおねがいいたします。
dairygoods様にお教えいただいた
上記のリンクについては私の力不足で読めませんでした。
まだまだクラスの勉強が足らないようです・・・
お騒がせしました上記についてはGetKeybo[a]rdState で見つかりました。
あと、調査中に
{
GetKeySatate()に似た関数で,GetAsyncKeySatate()というのがあります.
これは,常に関数が呼ばれた時点でのキーボード状態を問い合わせるものです.
}
とあったので、コレはGetKeyStateのかわりに組みこんだのですが
それでも上手くいきません。ummmm
GetKeybordState() ?なにこれ???
GetKeyboardState() これの間違い?ですよね。
BOOL GetKeyboardState(
PBYTE lpKeyState // address of array to receive status data
);
仮想キーコードは、WINUSER.H
user32.lib を使用
すみません、間違い。
GetKeybordState() → GetKeyboardState()
使い方
BYTE keybuf[256];
GetKeyboardState(keybuf);
if(keybuf[VK_UP] & 0x80) //上キー押されてる
GetAsyncKeyboard()も同様。
私のアプリケーションではこれでうまくいってます。
入力判定はWM_KEYDOWNではなく、WM_TIMERで処理してます。
WM_TIMERはSetTimer()で。
また間違い。
GetAsyncKeyboard()も同様。 ← うそ
そんなAPI無いです、すみません。
SunPac様、blackwind様、ご返信ありがとうございます。
SunPac様にお教えいただいた方法で実現することができました!
しかも前よりスピードUP(^^
ありがとうございました。
キャラクタがチラついているようですが
dairygoods様におしえていただいたリンクで勉強してみます。
しかし、GetStateKey、GetAsyncKeyStateの使い方についてはちょっと心残りです、
どなたか、詳しい方ご教授ください。
ちなみに実現したプログラムは下記です。
Yahooブリーフケース (pika.zip)
http://briefcase.yahoo.co.jp/
ID: programing_00
password: aaabbb
判定するキーが多い場合はGetKeyboardState()で一気に状態を取得して、
それほど多くない場合はGetKeyState()かGetAsyncKeyState()を使って個別にキーの
状態を取得するのが一般的かと。
GetKeyState()とGetAsyncKeyState()の区別はキーが押されてすぐに反映されるのが後者
で、(つまりキーが押されて発生するハードウェア割り込みに対応する)リアルタイム
性を重視するならこちらなのでしょう。
GetKeyState()はメッセージキューに溜まっている物を見るようなので、何かの処理中に
キーが押されてもGetKeyState()は反映されないのです。
ちょっと実験。
GetAsyncKeyState()とGetKeyState()はどちらが早いか。
100000回それぞれ実行したところ・・・
GetAsyncKeyState() : 31ms
GetKeyState() : 47ms
となりました。
やはりリアルタイム性重視ならGetAsyncKeyState()を使うべきかな。
ちなみにGetKeyboardState()は281msでした。
環境によって値はもちろん変わりますが・・・
SunPac様、ご教授たいへんありがとうございます。
>>GetKeyState()はメッセージキューに溜まっている物を見るようなので、何かの処理中に
>>キーが押されてもGetKeyState()は反映されないのです。
それで、(上・右同時押し)→(上だけ離す)に対応できなかったのかな。
とりあえず、複数のキー判定はGetKeyboardState()
単一のキー判定はGetAsyncKeyState() ということで、納得できました。
皆様方、丁寧な対応ありがとうございました。またよろしくおねがいいたします
>>>GetKeyState()はメッセージキューに溜まっている物を見るようなので、何かの処理中に
>>>キーが押されてもGetKeyState()は反映されないのです。
>
>それで、(上・右同時押し)→(上だけ離す)に対応できなかったのかな。
>
WM_TIMERを使ったから良かったのでは?
前提条件(キーリピートに関して):
同時押しと言っても人間が押下するので同時と言うのは無理です。
キーボードを一定時間押下しつづけるとリピート機能が働き、WM_KEYDOWNイベントが発生する
のですが、それは最後に押されたキーのみです。
今回の例の「上・右同時押し」を行った時に上を押すのが遅かった為にKEYDOWNイベントの発生
順番が右、上の順で起こり上が最後に押下されたキーとなっているんだと思います。KEYDOWNは
上キーが押下されている間発生するのだが、上キーが放されることによりKEYDOWNイベントが発
生する要因がなくなってしまった。もちろんKEYDOWNでキーの監視をしていたのでイベントが発
生してこないと監視できない。
暇人様、ご教授ありがとうございます。
VM_KEYDOWNは、同時キー押し時のイベント処理にはむいていないのですね(^^;
ご指摘のようにVM_TIMERでGetAsyncKeyを使っても大丈夫でした。
SunPac様が
>>GetAsyncKeyState() : 31ms
>>GetKeyState() : 47ms
>>GetKeyboardState()は281ms
とお教えくださったので、処理速度を考えると
やはり、GetAsyncKeyState()を使った方がよいみたいですね