投稿
nobu divine-creator
ボタン入力待ちにしているはずなのに、そこでプログラムが止まらずに進んでしまった…という経験がある人はいますか? ちなみに、ボタン入力はリピートにしていないので、押し続けても進まないはずです…。 また、ボタンの二度押しはしていないはずなので、それで進んだという訳でもないようです…。 この原因に心当たりのある方は、情報を教えてください! あと、WAITを入れることで止まるようになりましたが、本来ならボタン入力待ちだけで止まるはずなんですよね…。
1そうだね
プレイ済み
返信[1]
親投稿
ボタンの入力はVSYNC(やWAIT)のタイミングで更新されるみたいです。なのであまりに早く処理してしまうとボタン情報が更新されないのでずっと押しているような状態(として処理)されてしまう感じみたいです。 なので僕はボタン処理の時は必ずVSYNCが一度でも通るか注意しています。また同じ理由で単純なボタン入力待ちの場合、 REPEAT:VSYNC:UNTIL BUTTON(2) AND 16 のようにREPEATを使っています。REPEATなら必ずVSYNCを通った後にボタン判定に進むというのが理由です。 一応僕的にはそんな感じでした〜。
0そうだね
プレイ済み
返信[2]
親投稿
nobu divine-creator
回答ありがとうございます♪ しかし、私がボタン入力待ちに使っているのが、そのREPEATのループなので、必ずそこを通ってから進むはずなんですよね…? だから、何故止まらずに次の表示へ進んでしまうのか…不思議でした…。 何度試しても表示されないので、結局WAITを入れて止める方法にしました…。 すでに問題の解決はしているのですが、まだ謎は残っています…(?_?)。
0そうだね
プレイ済み
返信[3]
親投稿
それはおかしいですねぇ…。どういうコードなのかわからないのでなんとも言えませんが、ちょっとした見落としなどの可能性もないですかね? 僕がやったことがあるのはうっかりREPEATを抜けてから次のメインループに入った後のボタン処理の間にVSYNCがなくて連続的に反応してしまったことはあります。(VSYNCをループの最後に入れてたので) またBUTTON(2)のつもりでBUTTON(1)を指定してしまった凡ミスもありますが、正常に処理しているときは大丈夫だったです。 INPUTやダイアログなどのシステム系の入力待ちが入る処理から抜けたときはハマりそうな感じがありましたが、気をつけてれば一応大丈夫でした。 なんででしょうね〜…。
0そうだね
プレイ済み
返信[4]
親投稿
nobu divine-creator
IFを使って選択肢を選んで分岐して、結果を表示するという流れだったのですが、分岐した結果表示をすっとばして、その後の合流先が表示されてしまっていました…。 分岐した先では、スプライトの表情を変え、台詞を表示してボタン入力を待ち、その先へ進むはずだったんですけど、スルーされてしまいました…orz。 台詞とボタン入力待ちループの間にWAITを入れたら、表情の変化も台詞も正しく表示されましたが、スルーされた原因は不明のままです…。
0そうだね
プレイ済み
返信[5]
親投稿
なかなか気になりますねー…。 大体は何らかのミスがあることが多くはありますが、本当にシステムの問題の可能性もなくはないのでなんともいえませんよね。 まあでもとりあえず回避法(WAIT)を見つけてそれで正常に動いているなら現時点はOKと言うことにするしかないのかなぁ、って感じですね。 不具合が発生した状態のプログラムなどを公開キーであげてもらえたり出来るなら詳しく調べてみることも出来ると思いますが、現時点ではそんな感じだと思います〜。
0そうだね
プレイ済み
返信[6]
親投稿
nobu divine-creator
完成するまで公開はできないので、とりあえずはこのまま進めることにします! 情報ありがとうございました♪
0そうだね
プレイ済み
返信[7]
親投稿
けい kei0baisoku
推測ですが、まずはやっぱりVSYNCを通ってないパターンが一番多いですが、通ってもVSYNCだと必ず同期待ちする保障はないので、場合によっては素通りすることがあります。 WAIT 1は、その行で必ず次のフレームになるまで待ちますが、VSYNC 1は「最後にVSYNCしてからまだ1フレーム経ってなかったら」という条件が付きます。 (WAITとVSYNCの違いの部分です)
0そうだね
プレイ済み
返信[8]
親投稿
nobu divine-creator
そうですね…♪確かに、VSYNCのせいというのは、あるかもしれません…。 だとしたら、WAITによる解決は正しい!ってことになりますかね?
1そうだね
プレイ済み
返信[9]
親投稿
けい kei0baisoku
そうですね、私の推測通りですと、前提として最後にVSYNCしてから今回VSYNCするまでに重い処理をやっていることになります。 それでしたら解決策として、VSYNCだと不適切だからWAITで待つ、っていうのは割と正攻法だと思います。
0そうだね
プレイ済み
返信[10]
親投稿
確かに処理が重すぎる事はあまり考えてませんでした。そもそもとして1ループの処理に2フレーム以上かかるとあまりボタンの効果は期待できないようなことをどこかで聞いたような聞かなかったような…。
0そうだね
プレイ済み
返信[11]
親投稿
MIKI ifconfig
1そうだね
プレイ済み
返信[12]
親投稿
マギー M191246
例えば プログラム実行 …VSYNC 1 プログラム終了 … 紅茶を飲む。 … プログラム実行 …VSYNC 1… ↑前回のVSYNCから、何万フレームも 過ぎているので素通り。 といったことはないでしょうか? この時は、プログラムの頭に 基準用のVSYNCを入れるとできるみたいです。 WAITの方が簡単ですけど。
0そうだね
プレイ済み
返信[13]
親投稿
nobu divine-creator
皆さん、情報並びに解決案をありがとうございます♪ これまでに、自分で質問したり、他の人がした質問に書かれていた情報を読んだりして、VSYNCとWAITの違いや使用例を学んできたつもりでしたが、まだまだ知らないことが沢山あるのですね! 意外と素通りされてしまうことがあることに驚きましたΣ(゚Д゚)! とりあえず、VSYNCが無視されたらWAITの出番♪という感じに覚えておきます!
0そうだね
プレイ済み
返信[14]
親投稿
Godot orz_127
何か根本的なところを勘違いしているような。 「ボタン入力はリピートにしていないので、押し続けても進まないはずです…。」 リピートの設定に関係無く、BUTTON()は基本的にとまらず、進みますよ。 違ってたらすみません。 ちょっと気になりました。 入力処理のリストが無いとどういうことになっているのかよくわかりません^^;
0そうだね
プレイ済み
返信[15]
親投稿
nobu divine-creator
ボタンのリピートについては、BUTTON(2)にしていれば押しっぱなしでも繰り返しにならないという意味で書いていました。 TERA(LL)さんの「読み捨て」という方法は、BUTTON(1)と(2)を並べておくことで、素通りされなくするということですね?! それって、意外とメジャーな方法なのでしょうか?初めて見ました…。
0そうだね
プレイ済み
返信[16]
親投稿
MIKI ifconfig
button(2) であっても、値が更新されるのは「一画面書き終わった時」なので、それまでは同じ値を返します。 while 1 ? button(2),button(2) wend を実行してみてちょ。
0そうだね
プレイ済み
返信[17]
親投稿
nobu divine-creator
うわわっΣ(゚Д゚;)!0が縦2列に一杯…!! これが、一画面書き終わる前に、ボタンが押された場合に起こる事ですね! つまり、状況によって、ボタンの効果は出なくなるということですね…。
0そうだね
プレイ済み
返信[18]
親投稿
TERA(LL) tera0413
はわわ。 間違いに、気がついたので、すぐに消したんですが、見られてましたか。 「読み捨て」については、BUTTON(1)とBUTTON(2)を並べる事でなく、同期前にボタン判定が重なってしまった場合の回避策で、でんぺんさんの書いてるREPEAT:VSYNC:UNTIL・・・で回避できなかったとのことなので、そのまま削除してました。 (次のボタン判定前に、なんらか値が入力されていたら、値が全部消えるまでそこでループさせる事です。) ちなみに、同じタイミングで別々の変数にBUTTON(1)とBUTTON(2)で入力を拾う事はすると思いますが、「読み捨て」って意図ではありません。
0そうだね
プレイ済み
返信[19]
親投稿
MIKI ifconfig
えっと 0 が並んでいるときに、ボタンを押してみてください。 一瞬 16 が並んだりしますよね。 1/60 秒の間 button(2) は同じ値を返します。
0そうだね
プレイ済み
返信[20]
親投稿
nobu divine-creator
16ですか?0の右隣に6が一瞬だけ見えますけど、1は見えませんでした…。 うえこうさんが貼ってくれたプログラムは、ボタンを押しっぱなしにしても確実に止まるということですか? これって、誰かに教わったもの?それとも、自分で考えだしたもの?もし、オリジナルだとしたら、凄いですね!♪
0そうだね
プレイ済み
返信[21]
親投稿
Godot orz_127
BUTTON()関数単体ではどうやっても入力待ちにはならないと思いますよ。 BUTTON()を実行した時点で0が返って来たら入力がなかったものとして もう一度BUTTON()を実行しなければなりません。 ()内の数値はどの状態を拾うかの指定なだけので、それで待ちになることはありません。 BUTTON()での入力で待ちを実装したいなら、0ならもう一度をループで続けて、0以外ならそれを入力値としてループを抜ける、と言う処理を作るしかないと思いますが、その点は大丈夫ですか?
0そうだね
プレイ済み
返信[22]
親投稿
VSYNCだとウエイトが入るかわからない(のでボタンが安定しない)というのが理由だとしたら、ボタン待ちは、 REPEAT:WAIT:UNTIL BUTTON(2)==#A みたいな感じなら正常に待つのだろうか…。というか駄目な状態に遭遇しないとテスト出来ないのでわからない…
1そうだね
プレイ済み
返信[23]
親投稿
nobu divine-creator
私が使用しているボタン入力待ちループは、 REPEAT ~ UNTIL BUTTON(2)という形式ですよ♪ それをGOSUBで呼び出すという方法を使っています。
0そうだね
プレイ済み
返信[24]
親投稿
REPEATの中にWAITが入ってるのがポイントなんですよ〜。VSYNCだとダメだと言われたのでWAITにしました。 ちなみにVSYNCやWAITが入ってないならダメなのは当たり前なのですけどね。
0そうだね
プレイ済み
返信[25]
親投稿
nobu divine-creator
以前にどこかで、ループの中に入れるのはWAITよりもVSYNCのほうが良いという意見を読んだことがあるのですけど、止まらなくて困るという場合には、WAITのほうが良いと考えれば良いのですかね?
0そうだね
プレイ済み
返信[26]
親投稿
速度を一定に保つためのメインループとかの場合はVSYNCの方がいいと思いますが、ボタン入力待ちなど速度と無関係の場合はどっちでもいいと思います。 ただ僕も上記ケースではVSYNCにしてましたが、VSYNCだと実質ウエイトが入らないことがある(メインループの場合はその方が便利ですが)ので、その結果としてボタンの判定がおかしくなるのであれば中身をWAITにする方法だとどうなのかなと思った感じです。 まあでも実際に不具合が出てないので試せないのでWAITにすれば直るのかはわかりませんけどね…
0そうだね
プレイ済み
返信[27]
親投稿
ちなみにもう一つの方法としては、 REPEAT:UNTIL BUTTON(2)==0 REPEAT:UNTIL BUTTON(2)==#A と2行書く方法もあります。これでも止まるとは思いますが念のためこの2行にも間にVSYNCとかWAITを入れとくと良いかもですね。
0そうだね
プレイ済み
返信[28]
親投稿
nobu divine-creator
さすがに2行(3行)書くという方法は、あまり使いたくないですね…。 全体の行数が増えてしまうのを避けるために、GOSUBで呼び出すという方法を使っていますので、REPEATの後をWAITにするという方法が良いですね♪
0そうだね
プレイ済み
返信[29]
親投稿
MIKI ifconfig
弾幕系とかだと万一処理が間に合わなかったとき、wait だとカクカク感が激しくなります。vsync なら目立たない可能性がある。そういう意味で vsync の方がいいといわれることがあります。 そもそもリアルタイムゲームでないなら、待たない場合がある vsync よりも、常に待つ wait の方が使い勝手がいいでしょう。 でんぺんさん REPEAT:wait:UNTIL BUTTON(2)==0 REPEAT:wait:UNTIL BUTTON(2)==#A の方が、消費電力が少ない可能性があります。button() の戻り値が変わるのは 1/60 に一度だけだから、それまでは100万回呼んでも同じ値しか返りません。CPUは無駄に全力でループすることになる。wait で、CPU が「待ち」に入れば、もしかしたら消費電力が抑えられるかもしれません。
0そうだね
プレイ済み
返信[30]
親投稿
nobu divine-creator
消費電力?!まさか、それほどの差が出るとは…!
0そうだね
プレイ済み
返信[31]
親投稿
MIKI ifconfig
ん? gosub 使ってるなら全体の行数はほとんど変わらないのでは? gosub @wait_a_button @wait_a_button REPEAT:wait:UNTIL BUTTON(2)==0 REPEAT:wait:UNTIL BUTTON(2)==#A return てことですよね?
0そうだね
プレイ済み
返信[32]
親投稿
そうですね〜。REPEATの間にVSYNCやWAITを入れなかったのは2行ならVSYNC関係なしに処理されているというのを表しているところもあったので僕も自分で使う場合はループの間にはなんらかのウエイト処理は入れちゃいますね。消費電力を無意識に意識してるところあるかもです。 あとGOSUBやユーザー関数化するなら行数はあまり関係ないのでは? というのはみきさんと同意見ですね〜
0そうだね
プレイ済み
返信[33]
親投稿
nobu divine-creator
ハッ!確かに、呼び出すのは一行なので、増えるのは一ヵ所だけですね…。何故、勘違いしてしまったのでしょう?
1そうだね
プレイ済み
返信[34]
親投稿
僕は人生がカクカクしてます。いえ、すいません。関係ありませんね…
0そうだね
プレイ済み