HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
0719
M-Sonkeyを使ってループ処理をすると最初が一瞬止まる?10解決


M-S

リンク

2019/7/19(Fri) 21:53:26|NO.87889

HSP初心者です。
キャラクターを上下左右のみ動かせる方法を探したところonkeyとgetkey(stick)の二種類を見つけ
他のキー割り込みをしたくないタイミングで使用する可能性が高いためなるべくならonkeyを使用したいのですが
onkeyを使うと、押した最初だけ一瞬ガクっと止まるのですが一瞬止まる理由がわかりません。

;onkeyによる記述(最初が一瞬ガクっと止まる)

;線画準備
screen 0,220,220 buffer 1:boxf color 100,100,100;透過用 boxf 0,0,20,20;■ ;↑線画準備ここまで↓ここから線画ループ *printing onkey gosub *move gsel 0:redraw 0 color 255,255,255:boxf gmode 2,100,100 pos x,y:gcopy 1,0,0,20,20;■ redraw 1:wait 10 goto *printing ;↑線画ループここまで↓ここからonkey処理 *move if wparam=37:if x<1:else:x=x-20 if wparam=38:if y<1:else:y=y-20 if wparam=39:if x>190:else:x=x+20 if wparam=40:if y>190:else:y=y+20 return ;↑onkey処理ここまで


;getkeyによる記述(特に問題なく動いている?)

;線画準備
screen 0,220,220 buffer 1:boxf color 100,100,100;透過用 boxf 0,0,20,20;■ ;↑線画準備ここまで↓ここからgetkey処理 *printing getkey move,37:if move=1:if x<1:else:x=x-20 getkey move,38:if move=1:if y<1:else:y=y-20 getkey move,39:if move=1:if x>190:else:x=x+20 getkey move,40:if move=1:if y>190:else:y=y+20 ;↑getkey処理ここまで↓ここから線画ループ gsel 0:redraw 0 color 255,255,255:boxf gmode 2,100,100 pos x,y:gcopy 1,0,0,20,20;■ redraw 1:wait 10 goto *printing ;↑線画ループここまで


記述ミスをしていない限りonkeyとgetkeyの処理以外はほぼ同じなはずなのですが・・・。
onkeyの一瞬止まる挙動を解決する事は出来ますでしょうか?



この記事に返信する


科学太郎

リンク

2019/7/19(Fri) 22:32:41|NO.87890

> onkeyを使うと、押した最初だけ一瞬ガクっと止まるのですが一瞬止まる理由がわかりません。
こちらは MS-DOS 時代から Windows OS を使ってる経験者です。
昔の古い MS-DOS という OS には、キー情報はキーバッファに入る仕組みでしたね。
ここから Windows OS の内部を推測すると次のような状況だと思います。

> ;onkeyによる記述(最初が一瞬ガクっと止まる)
onkey 命令は WM_KEYDOWN、WM_KEYUP メッセージを発生させますね。
こちらは Windows OS の内部でキーバッファという一時的にキー情報を保存する領域に
キーコード情報が格納されるはずです。

> ;getkeyによる記述(特に問題なく動いている?)
こちらはキーバッファは関係なくて、実行時のキー情報を取得して即終了する命令です。
この違いからキーバッファーに入る onkey 命令は、連続して同じキーコード値が
入らないようにするために Windows OS の内部でウェイトを入れてるのだと思います。

MS-DOS 時代でもキーをずーーーーっと押しても押した一瞬は最初の1つだけで
しばらくしないと連続したキー情報を取得できません。

よって、HSP の問題や、記述の問題ではなくて Windows OS の仕組み上、
仕方がない動作かもしれません。

> 記述ミスをしていない限りonkeyとgetkeyの処理以外はほぼ同じなはずなのですが・・・。
> onkeyの一瞬止まる挙動を解決する事は出来ますでしょうか?
出来ないと思いますけど。



M-S

リンク

2019/7/20(Sat) 01:17:09|NO.87892

科学太郎様、早速のご回答まことにありがとうございます!
onkeyの一瞬止まる挙動はOS内部によるものであればHSP側ではどうにもならさそうですね・・・。
まだ触り始めの段階なので(キー割り込み部分を妥協するか否かも含め)もう少し色んな方法を探ってみようと思います。



Tsuyoshi

リンク

2019/7/20(Sat) 10:08:29|NO.87894

onkeyは一度実行したら、その後ずっとキー入力を監視するので、onkeyで書くとすれば、


onkey gosub *move *printing //処理 goto *printing *move //処理 return

こんな感じでしょうか。

検証はしていませんが、onkeyがループ内に入っているのが一瞬ガクッとなる原因かと思います。


"他のキー割り込みをしたくないタイミングで使用する可能性が高い"というのがよく分かりませんが、
onkeyはキーボードのあらゆる入力を検知するので、上下左右キー以外検知したくないという意味であれば、
むしろonkeyを使うべきではないと思います。

ゲームで使うとすれば、例えばどんな状況からでもESCキーを押したらプログラムを終了させたいみたいな時に
onkeyを使うかもしれません。



M-S

リンク

2019/7/20(Sat) 20:37:05|NO.87899

Tsuyoshi様、ご回答いただきありがとうございます!

>onkeyで書くとすれば、
試してみましたがやはり最初だけ止まってしまうようです。
まだ始めたばかりなので他の方法を探してみようと思います。

>"他のキー割り込みをしたくないタイミングで使用する可能性が高い"というのがよく分かりませんが、
想定(可能性)では、歩行グラアニメを入れながら移動処理(指定した位置まで徐々に動かす)をした場合に
もし移動処理中にキー割り込みが出来ると、記述のやり方によっては想定外の挙動になる&移動処理中のみ一時的にキー割り込み不可にしていれば割り込み対処できるのだろうかと思った次第です。
(処理中だけ一時的にキー操作不可(割り込みさせない)にさせる方法でonkeyで制御できるならそれが無難なんだろうかとも思っていました)



科学太郎

リンク

2019/7/20(Sat) 21:28:02|NO.87901

> 想定(可能性)では、歩行グラアニメを入れながら移動処理(指定した位置まで徐々に動かす)をした場合に
この歩行アニメをループで組んでるのでしょうか?
それともゲーム・ループ内で歩行アニメ用のカウンタで描画を切り替えてるのでしょか?

何となくループ内で歩行アニメの描画を行ってる途中で
キー割り込みが発生するとループを抜けることから
キー割り込みを禁止にしたいように見えますが…。

もしも、このような場合であれば、ゲーム・ループ内で
歩行アニメ用のカウンタを用意してから描画をすれば良いと思います。
こちらも昔、若いころに(24歳ごろ)のときにゲームを作っていたので
キー割り込みを無視したくなる気持ちが分かりますね。

なお、昔ゲームを製作したときには、
テトリス・ゲームのような場合には、キー・バッファから情報を取得。
シューティング・ゲーム、RPGゲームでは、スムーズにするために
キー・バッファから取得するのではなくて HSP でいう getkey 命令に
相当する関数で取得しました。

そうしないとキーをずーーーーっと押したときにスムーズに移動などが
行えないからです。(参考までに)

あとシューティング・ゲーム、RPGゲームで移動処理は getkey 命令で行い
ロード、セーブ、終了メニューなどは WM_KEYDOWN、WM_KEYUP メッセージを使う。
このような方法で使い分けた方が良いと思います。



リンク

2019/7/20(Sat) 21:38:30|NO.87902

onkey および WM_KEYDOWN は、キーを押し続けたときに、最初は0.5秒ぐらい、次からは0.05秒ぐらいで反応します。これはWindowsの仕様なので、どうしようもありません。 getkey を使う必要があります。



M-S

リンク

2019/7/21(Sun) 14:22:32|NO.87905

>何となくループ内で歩行アニメの描画を行ってる途中で
>キー割り込みが発生するとループを抜けることから
>キー割り込みを禁止にしたいように見えますが…。
目的は斜め移動の防止になります。
少しレトロな路線にしたいため、純粋に縦と横にしか移動できないようにしたいのですが、割り込みが出来ると上下左右のキーをガチャガチャさせると斜めに移動してしまう事が多く、getkeyで防止する方法がなかなか見つからなかった(思いつかなかった)ためonkeyはどうなのだろうかと思い至りました。

onkeyですがイメージとしてはこんな感じになります。
(若干位置がズレてますがマス目の中に収まるように移動させる感じです)

/*---線画準備---*/
screen 0,200,200;メイン画面のサイズ指定 buffer 1;コピーするためにバッファ画面を用意 boxf;透過用(color 0,0,0) color 100,100,100:font "MS Pゴシック",19,1:mes "´↓";画像の代わりに´↓ buffer 2;コピーするためにバッファ画面を用意 line 0,0,0,200:line 0,0,200,0 tate=19:yoko=19 repeat 10;縦線 line tate,0,tate,200 tate=tate+20 loop repeat 10;横線 line 0,yoko,200,yoko yoko=yoko+20 loop tate=0:yoko=0;マス目の位置指定に利用 gsel 0;さっきまでバッファ画面を操作していたのでメイン画面に切り替える /*---↑線画準備ここまで↓ここから変数準備---*/ x=0:y=0;線画場所の横と縦の位置指定 anime=0;アニメーション用・徐々に増加する animeprint=0;変数animeの値によってgcopyする場所(開始場所)を変える count=0;onkeyを0or1にするための変数 jojo=2;徐々に動く値 /*---↑変数準備ここまで↓ここからループ線画---*/ onkey gosub *move;左・上・右・下を押すと動く *printing if count=1:onkey 0:else:onkey 1;動いてる最中は他キーの割り込みを防止(したい) redraw 0;チラつき防止前 pos tate,yoko gcopy 2,0,0,200,200;マス目 gmode 2,100,100;黒を透過 if anime=0:animeprint=0:else:if anime=20:animeprint=20:else:if anime=40:animeprint=40:else:if anime=60:animeprint=60:else:if anime=80:animeprint=0:anime=0;´↓い鮟腓縫▲縫瓠璽轡腑鵑垢 pos x,y:gcopy 1,animeprint,0,20,20;´↓ anime+;アニメーションのフラグ /*--ここからキーを押されたら動作するフラグ--*/ /*--0なら反応しない・1になる→押されたら徐々に対応する変数の中身が増える--*/ /*--増えてる間キー割り込みをできなくする・一定増えたらリセット&キー割り込みをできるようにする--*/ if left=0:else:if left>21:left=0:count=0:else:x=x-jojo:left=left+jojo;左 if up=0:else:if up>21:up=0:count=0:else:y=y-jojo:up=up+jojo;上 if right=0:else:if right>21:right=0:count=0:else:x=x+jojo:right=right+jojo;右 if down=0:else:if down>21:down=0:count=0:else:y=y+jojo:down=down+jojo;下 /*--キーを押されたら動作するフラグここまで--*/ redraw 1;チラつき防止後 wait 1;wait入れないと止まる goto *printing /*---↑線画ループここまで↓ここからonkey処理---*/ *move if wparam=37:if x<20:else:left=2:count=1;左 if wparam=38:if y<20:else:up=2:count=1;上 if wparam=39:if x>170:else:right=2:count=1;右 if wparam=40:if y>170:else:down=2:count=1;下 return;gosub使用時必須 /*---↑onkey処理ここまで---*/



M-S

リンク

2019/7/21(Sun) 14:23:05|NO.87906

猫様。
ご回答いただきありがとうございます!
>最初は0.5秒ぐらい、次からは0.05秒ぐらいで反応します。
最初はそれくらい止まるんですね・・・仕様上どうしようもないので改めてgetkeyで方法を探してみようと思います!



あり

リンク

2019/7/21(Sun) 19:42:41|NO.87907

>目的は斜め移動の防止になります。
ということだけが目的であるならstickで十分なのでは?

/*---線画準備---*/ screen 0,200,200;メイン画面のサイズ指定 buffer 1;コピーするためにバッファ画面を用意 boxf;透過用(color 0,0,0) color 100,100,100:font "MS Pゴシック",19,1:mes "´↓";画像の代わりに´↓ buffer 2;コピーするためにバッファ画面を用意 line 0,0,0,200:line 0,0,200,0 tate=19:yoko=19 repeat 10;縦線 line tate,0,tate,200 tate=tate+20 loop repeat 10;横線 line 0,yoko,200,yoko yoko=yoko+20 loop tate=0:yoko=0;マス目の位置指定に利用 gsel 0;さっきまでバッファ画面を操作していたのでメイン画面に切り替える /*---↑線画準備ここまで↓ここから変数準備---*/ x=0:y=0;線画場所の横と縦の位置指定 anime=0;アニメーション用・徐々に増加する animeprint=0;変数animeの値によってgcopyする場所(開始場所)を変える count=0;onkeyを0or1にするための変数 jojo=2;徐々に動く値 /*---↑変数準備ここまで↓ここからループ線画---*/ *printing if count=0 { /*--- 移動処理が終わるまでキー入力をさせない ---*/ stick key, 15 if key=1:if x<20:else:left=2:count=1;左 if key=2:if y<20:else:up=2:count=1;上 if key=4:if x>170:else:right=2:count=1;右 if key=8:if y>170:else:down=2:count=1;下 } redraw 0;チラつき防止前 pos tate,yoko gcopy 2,0,0,200,200;マス目 gmode 2,100,100;黒を透過 if anime=0:animeprint=0:else:if anime=20:animeprint=20:else:if anime=40:animeprint=40:else:if anime=60:animeprint=60:else:if anime=80:animeprint=0:anime=0;´↓い鮟腓縫▲縫瓠璽轡腑鵑垢 pos x,y:gcopy 1,animeprint,0,20,20;´↓ anime+;アニメーションのフラグ /*--ここからキーを押されたら動作するフラグ--*/ /*--0なら反応しない・1になる→押されたら徐々に対応する変数の中身が増える--*/ /*--増えてる間キー割り込みをできなくする・一定増えたらリセット&キー割り込みをできるようにする--*/ if left=0:else:if left>21:left=0:count=0:else:x=x-jojo:left=left+jojo;左 if up=0:else:if up>21:up=0:count=0:else:y=y-jojo:up=up+jojo;上 if right=0:else:if right>21:right=0:count=0:else:x=x+jojo:right=right+jojo;右 if down=0:else:if down>21:down=0:count=0:else:y=y+jojo:down=down+jojo;下 /*--キーを押されたら動作するフラグここまで--*/ redraw 1;チラつき防止後 wait 1;wait入れないと止まる goto *printing



M-S

リンク

2019/7/21(Sun) 19:59:55|NO.87908

あり様。ご回答いただきありがとうございます!
あり様の記述でonkey以外での望み通りの動きが出来ました・・・!
>ということだけが目的であるならstickで十分なのでは?
getkey(stick)で斜め移動させないようにする記述がなかなか思いつかず、思いついたものを試行錯誤するもうまくいかずで
停滞してしまったためonkeyで試しておりました。


onkeyでは出来ない代わりにgetkey(stick)でもキー割り込みを防止できる方法がわかったため
ここで解決とさせていただきます。
ご協力いただきました皆様、ご回答とアドバイスをいただき誠にありがとうございました!



ONION software Copyright 1997-2021(c) All rights reserved.