トピック
beans taku-binzu

助言お願いします。

添付画像のプログラムを実行すると私のイメージでは、 1,Aボタンを押すまでREPEATのループが行われる。 2,Aボタンを押すと@LOOPに移動し、Aボタンを押すまでループ 3,@LOOP内でAボタンを押すと@CHECKへ移動し変数Aの値によって@FIN、@FIN_1、@FIN_2に飛ばす。 という感じになってるのですが、実行してみると 1,REPEATループでAボタンを押す 2,@FINへジャンプ←? といった感じです。なぜですか?
0そうだね
プレイ済み
返信[1]
親投稿
beans taku-binzu
[訂正] @FIN_1、@FIN_2→@FIN_2、@FIN_3 すいませんミスりました。
0そうだね
プレイ済み
返信[2]
親投稿
みむ*mim hidemimtp
BUTTONは取得したときに毎回新たな値が取得できるのではなく、1フレームごとに更新されます。 なので、Eが#Aなら、BBも#Aです。 8行目に「VSYNC」を入れたら思い通りの動作をするかなと思います。 BUTTON(1)よりBUTTON(2)の方がいいかも?
3そうだね
プレイ済み
返信[3]
親投稿
beans taku-binzu
[訂正] 添付画像のプログラムを実行すると、正しくは、 1,REPEATループでAボタン 2,@LOOPへ移動(「こんちくわ」が表示されたため多分…) 3,Aボタンを押してないのに@FINへジャンプ と動きました。
0そうだね
プレイ済み
返信[4]
親投稿
つぎのループに移動する時WAIT 1を挟んでください。
1そうだね
プレイ済み
返信[5]
親投稿
みなさんが言っているようにボタン情報は一定時間(1フレーム)毎に更新されるので、間にVSYNCやWAITが入らないと変化しない(前のボタン情報のまま)の場合があります。 なのでボタン処理の後にまたすぐボタン処理がある場合は、その間にVSYNCやWAITを経由するか確認して、経由しない場合は間に追加するなどしてボタン情報を更新してあげる必要があります。 基本的にVSYNCでも問題ないとは思いますが、ボタン情報を更新するという意図であれば確実性を重視してWAITにするという方針もあります。 とりあえずどちらでも良いので試してみて確認してみてください。
2そうだね
プレイ済み
返信[6]
親投稿
この場合はWAITよりもVSYNCが適しています。 WAITは単純に一定時間を待機させるのに対し VSYNCは画面の周期に合わせることを目的としているからです。 WAITの場合は、メインループの重さにもよりますが、まれに取りこぼします。
0そうだね
プレイ済み
返信[7]
親投稿
beans taku-binzu
皆様の助言を参考に再びプログラムしてみたのですが、私の技術不足のようでやっぱり@LOOPのループがうまくいきません。ごめんなさい(「ループしました」の表示がされてなく、そのまま@FINにジャンプしてしまいました。) 修正後のプログラムを添付いたしますので、もう一度お力を貸して下さい。 宜しくお願いします!
0そうだね
プレイ済み
返信[8]
親投稿
あれ? あまさと しおんさんのコメントに対する意見ですが、僕の認識ではVSYNCの方が取りこぼす可能性があるような気がしています。 と言うのは、WAITは必ず最低1フレームは待機する(のでVSYNC周期は確保される)のに対し、VSYNCはメインループの重さによってはウエイトが入らない(から取りこぼす可能性がある?)からです。 といいつつ僕も細かい内部の動作はわからないので正確な事はわからないです。ただ僕は前にVSYNCで処理していたときに取りこぼしたのかうまく処理できなかったことがあったので、以降はメインループのVSYNCではない時でボタンの情報が確実に欲しいときは念のためにWAITにしています。 おそらくこの辺の挙動についてはおちゃめさんが詳しいような気がするのですが、間違っていたらすいません。
1そうだね
プレイ済み
返信[9]
親投稿
先ほどは少し誤解がありました。WAITでもいいです。 訂正します。 誤「この場合はWAITよりもVSYNCが適しています。」 正「更新周期に合わせる目的にはWAITよりもVSYNCを使います。」 プログラムを開始してから1回目のVSYNCがどんな挙動をするのか自信がないです…(解説ください)
2そうだね
プレイ済み
返信[10]
親投稿
ただ、 WAIT 1の場合は1ループの所要時間は 1フレーム+ループの実行時間 VSYNC 1の場合は1ループの所要時間は 1フレームかループの実行時間のうち大きい方 ループ実行時間を0.1fとした場合 VSYNC→1.0 1.0 1.0 1.0 1.0 1.0 WAIT→1.1 1.1 1.1 1.1 1.1 1.1 10回ごとに取りこぼすのではないか??
0そうだね
プレイ済み
返信[11]
親投稿
VSYNCで「押したのに反応しない」ことは起きたとすれば、いわゆる「処理落ち」(1ループの時間が指定時間をオーバーする)ではないでしょうか?
1そうだね
プレイ済み
返信[12]
親投稿
ちょっと試してみましたが、とりあえず3行目の後にもVSYNCをいれたら正常に動作するようですよ。他のところもVSYNCで問題なさそうです。 僕も更新周期を合わせるという意図ではVSYNCの方が適していると思っています。のでループの中ではVSYNCを使うんですが、上記のようにボタンの情報更新のタイミングはイマイチ自信が持てないので、場合によってはWAITを使うようにしたりもしています。 とくにDIALOGやINPUT命令の後のタイミングとかだとボタン情報が想定外になった事があった気がするんですよね。なので上記の命令の後にはWAITをいれて次のボタン情報(メインループなど)に備えたりすることもあります。 と言いつつバージョンアップなどで細かい挙動は変わってる可能性もありますし、もしかしたら今ならVSYNCだけで問題ないのかなって思ったりもしますけどね。 >あまさと しおんさん
1そうだね
プレイ済み
返信[13]
親投稿
INPUTとか「それ自体に待機が含まれている」命令の直後が狂う、なるほど。 そのは思いつかなかった。
0そうだね
プレイ済み
返信[14]
親投稿
ちなみに「Aボタンが離されるまで進まない」という意図に忠実にプログラムを組むとこんな感じでしょうか。 WHILE BUTTON(2) AND #A WEND
1そうだね
プレイ済み
返信[15]
親投稿
今までの発言をふまえ、僕の場合は「Aボタンが離されるまで進まない」を実現する定型文的な処理は、今のところ下記のように落ち着きました。==はANDでもいいです。(ケースバイケース) REPEAT:WAIT:UNTIL BUTTON(2) == #A REPEATを使い、先にWAITを入れる事でボタン情報を安定させて、その後のボタン判定でループをさせるという意図です。もしVSYNCの動作が確実ならループの中はVSYNCでもいいですね。 この辺の書き方はプログラマーの好みで変わったりもするのが面白いところかなと思ったりもします。(REPEATを使うか使わないかなども含めて)
1そうだね
プレイ済み
返信[16]
親投稿
beans taku-binzu
うおお!ありがとうございます。 皆様のアドバイス通りに修正したら正しく動きました! ありがとうございました。
1そうだね
プレイ済み
返信[17]
親投稿
おちゃめ ochame_nako
あまさとしおんさんへ あくまでVSYNCはタイミングを取るための命令であり、前回のVSYNCからの経過時間によって動作が変わるため指定時間待ってくれる保証はできません。 詳しくは「プチコン3号入門講座」に書いてあります。(VSYNCとWAITに関してここまで詳細解説をしているのはこの講座だけ!) でんぺんさんへ Aボタン入力待ちならばそれが最適解でしょうね。 「プチコン3号入門講座」に書いているようにVSYNCは確実な待ちには使えないしWHILE~WENDでは入り口チェックであるため実行されない恐れがありますからね。(WHILE 1~WENDでAボタンを押したらBREAKという記述ならばいいけどREPEAT~UNTILと比べて冗長になってしまう)
0そうだね
プレイ済み
返信[18]
親投稿
おちゃめ ochame_nako
ちなみに常時60fps以上で動作しているプログラムのメインループ内に入れた場合はVSYNC 1とWAIT 1は同じ挙動となります。(厳密に言えば最初の1回のみVSYNCの方ははスキップされる可能性があるけど見た目では全く違いが分からない)
0そうだね
プレイ済み
返信[19]
親投稿
おちゃめ ochame_nako
「VSYNCが確実な待ちに使えない」というのがどういう意味かはREPEAT:WAIT:UNTIL BUTTON(2)==#AとREPEAT:VSYNC:UNTIL BUTTON(2)==#Aの動作を比較してみればよく分かります。 前者はRUN+Aボタンで実行時も正常動作するのに対して後者は正常に動作しません。
1そうだね
プレイ済み
返信[20]
親投稿
beans taku-binzu
[追記] プロの方々の会話がありそうな流れみたいなので、しばらくトピックを開けておこうと思います。
0そうだね
プレイ済み
返信[21]
親投稿
おちゃめさん、詳しい解説、ありがとうございます。 僕は経験則でVSYNCでのボタン処理が失敗したのでWAITも利用するようにしたのですが、おちゃめさんのように色々と検証したうえでのデータがあると安心します。とりあえず確実な待ちのために利用する際はWAITという原則を利用しようかと思います。 待ち以外で次のメインループでVSYNCを使っている場合でボタン処理がおかしい時は、次のメイン処理に入る直前(もしくは直前のボタン処理の抜けた直後)に一度WAITを挟むと動作が安定しそうなので、そういう方針にしようかと思っています。 (とくにINPUTやDIALOG抜けの後とか) この手の話は他の方の意見も色々と考えるきっかけになったりして役に立ちます。これからもよろしくお願いします。
1そうだね
プレイ済み