カーソルキーの同時押し(斜め) – プログラミング – Home

カーソルキーの同時押し(斜め)
 
通知
すべてクリア

[解決済] カーソルキーの同時押し(斜め)


misae
 misae
(@misae)
ゲスト
結合: 21年前
投稿: 7
Topic starter  

はじめまして、
キャラクタをカーソルキーで動かすプログラムを作りたいのですが
斜め移動の判定がうまくできずに困っています。

一応ななめには動くことは動くのですが
たとえば、上と右を同時におして(つまり右斜め上)にキャラが移動中に
上だけを離すと、キャラがとまってしまいます。

環境はVC++ToolkitとCoreSDKです。
ソースを下記に保存いたしましたので、どなたかご教授おねがいいたします。

Yahooブリーフケース (source.zip)
http://briefcase.yahoo.co.jp/
ID: programing_00
password: aaabbb


引用未解決
トピックタグ
SunPac
 SunPac
(@SunPac)
ゲスト
結合: 22年前
投稿: 105
 

WM_KEYDOWNで、GetKeybordState()を使ってアローキーの状態をチェックすればOKかと。
DirectInput使ってもいいけど、こっちのが手軽でしょう。


返信引用
SunPac
 SunPac
(@SunPac)
ゲスト
結合: 22年前
投稿: 105
 

あ、ダメでした。
いきなり同時押しした場合、止まりますね。
WM_KEYDOWNではダメなようですので、Timerイベント等、ある間隔でGetKeybordState()
を使い、キー状態を取得すれば一応はOKですね。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

こちらは参考になりますか?
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200405/04050037.txt


返信引用
misae
 misae
(@misae)
ゲスト
結合: 21年前
投稿: 7
Topic starter  

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様にお教えいただいた
上記のリンクについては私の力不足で読めませんでした。
まだまだクラスの勉強が足らないようです・・・


返信引用
misae
 misae
(@misae)
ゲスト
結合: 21年前
投稿: 7
Topic starter  

お騒がせしました上記についてはGetKeybo[a]rdState で見つかりました。

あと、調査中に
{
GetKeySatate()に似た関数で,GetAsyncKeySatate()というのがあります.
これは,常に関数が呼ばれた時点でのキーボード状態を問い合わせるものです.
}
とあったので、コレはGetKeyStateのかわりに組みこんだのですが
それでも上手くいきません。ummmm


返信引用
blackwind
 blackwind
(@blackwind)
ゲスト
結合: 22年前
投稿: 18
 

GetKeybordState() ?なにこれ???
GetKeyboardState() これの間違い?ですよね。

BOOL GetKeyboardState(
PBYTE lpKeyState // address of array to receive status data
);

仮想キーコードは、WINUSER.H
user32.lib を使用


返信引用
SunPac
 SunPac
(@SunPac)
ゲスト
結合: 22年前
投稿: 105
 

すみません、間違い。
GetKeybordState() → GetKeyboardState()

使い方
BYTE keybuf[256];
GetKeyboardState(keybuf);
if(keybuf[VK_UP] & 0x80) //上キー押されてる

GetAsyncKeyboard()も同様。

私のアプリケーションではこれでうまくいってます。
入力判定はWM_KEYDOWNではなく、WM_TIMERで処理してます。
WM_TIMERはSetTimer()で。


返信引用
SunPac
 SunPac
(@SunPac)
ゲスト
結合: 22年前
投稿: 105
 

また間違い。

GetAsyncKeyboard()も同様。 ← うそ

そんなAPI無いです、すみません。


返信引用
misae
 misae
(@misae)
ゲスト
結合: 21年前
投稿: 7
Topic starter  

SunPac様、blackwind様、ご返信ありがとうございます。

SunPac様にお教えいただいた方法で実現することができました!
しかも前よりスピードUP(^^
ありがとうございました。

キャラクタがチラついているようですが
dairygoods様におしえていただいたリンクで勉強してみます。

しかし、GetStateKey、GetAsyncKeyStateの使い方についてはちょっと心残りです、
どなたか、詳しい方ご教授ください。

ちなみに実現したプログラムは下記です。

Yahooブリーフケース (pika.zip)
http://briefcase.yahoo.co.jp/
ID: programing_00
password: aaabbb


返信引用
SunPac
 SunPac
(@SunPac)
ゲスト
結合: 22年前
投稿: 105
 

判定するキーが多い場合はGetKeyboardState()で一気に状態を取得して、
それほど多くない場合はGetKeyState()かGetAsyncKeyState()を使って個別にキーの
状態を取得するのが一般的かと。

GetKeyState()とGetAsyncKeyState()の区別はキーが押されてすぐに反映されるのが後者
で、(つまりキーが押されて発生するハードウェア割り込みに対応する)リアルタイム
性を重視するならこちらなのでしょう。
GetKeyState()はメッセージキューに溜まっている物を見るようなので、何かの処理中に
キーが押されてもGetKeyState()は反映されないのです。


返信引用
SunPac
 SunPac
(@SunPac)
ゲスト
結合: 22年前
投稿: 105
 

ちょっと実験。

GetAsyncKeyState()とGetKeyState()はどちらが早いか。
100000回それぞれ実行したところ・・・

GetAsyncKeyState() : 31ms
GetKeyState() : 47ms

となりました。
やはりリアルタイム性重視ならGetAsyncKeyState()を使うべきかな。
ちなみにGetKeyboardState()は281msでした。
環境によって値はもちろん変わりますが・・・


返信引用
misae
 misae
(@misae)
ゲスト
結合: 21年前
投稿: 7
Topic starter  

SunPac様、ご教授たいへんありがとうございます。

>>GetKeyState()はメッセージキューに溜まっている物を見るようなので、何かの処理中に
>>キーが押されてもGetKeyState()は反映されないのです。

それで、(上・右同時押し)→(上だけ離す)に対応できなかったのかな。

とりあえず、複数のキー判定はGetKeyboardState()
      単一のキー判定はGetAsyncKeyState() ということで、納得できました。

皆様方、丁寧な対応ありがとうございました。またよろしくおねがいいたします


返信引用
暇人
 暇人
(@暇人)
ゲスト
結合: 23年前
投稿: 19
 

>>>GetKeyState()はメッセージキューに溜まっている物を見るようなので、何かの処理中に
>>>キーが押されてもGetKeyState()は反映されないのです。
>
>それで、(上・右同時押し)→(上だけ離す)に対応できなかったのかな。
>
WM_TIMERを使ったから良かったのでは?

前提条件(キーリピートに関して):
同時押しと言っても人間が押下するので同時と言うのは無理です。
キーボードを一定時間押下しつづけるとリピート機能が働き、WM_KEYDOWNイベントが発生する
のですが、それは最後に押されたキーのみです。

今回の例の「上・右同時押し」を行った時に上を押すのが遅かった為にKEYDOWNイベントの発生
順番が右、上の順で起こり上が最後に押下されたキーとなっているんだと思います。KEYDOWNは
上キーが押下されている間発生するのだが、上キーが放されることによりKEYDOWNイベントが発
生する要因がなくなってしまった。もちろんKEYDOWNでキーの監視をしていたのでイベントが発
生してこないと監視できない。


返信引用
misae
 misae
(@misae)
ゲスト
結合: 21年前
投稿: 7
Topic starter  

暇人様、ご教授ありがとうございます。

VM_KEYDOWNは、同時キー押し時のイベント処理にはむいていないのですね(^^;
ご指摘のようにVM_TIMERでGetAsyncKeyを使っても大丈夫でした。

SunPac様が
>>GetAsyncKeyState() : 31ms
>>GetKeyState() : 47ms
>>GetKeyboardState()は281ms
とお教えくださったので、処理速度を考えると
やはり、GetAsyncKeyState()を使った方がよいみたいですね


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました