投稿
adarah adarah
ボタンの状態を調べる命令「BUTTON」について質問があります。 ACLS @MAIN BTN=BUTTON(2) IF BTN !=0 THEN PRINT BTN; GOTO @MAIN ボタンを押した時だけその値を表示させるつもりで書いたのですが、ボタンを一度押すだけで何個も続けて表示されてしまいます。 ループの中に「VSYNC 1」を入れると思った通りの動作になるのですが、なにか思い違いをしているのでしょうか?
1そうだね
プレイ済み
返信[1]
親投稿
イーブン rein-2000
プリント命令を連続で使うと 使う度にどんどん改行されて、 下に行ってしまいます。 そういうときはメインループ内に CLSを入れて、さらに LOCATEで表示する位置を 表示させたい座標に 固定すれとうまく行くと思います。 何も表示されなかった場合はCLSを VSYNCの後にしてください。 それでも表示されない場合は VSYNCの後に FO~TO~NEXTで少し負荷を かけるといいと思います。
0そうだね
プレイ済み
返信[2]
親投稿
otta777 otta777a
以前自分もこれでなんで押した瞬間の入力が何度も取得 されるのか悩みました。 BUTTON(2)で押した瞬間1回だけボタンを押した状態取得を するはずが連続でボタンを押した状態が取得されて期待通りの 動作をしません。 プチコンの仕様でボタンを押した瞬間を取得するように指定しても 1フレームの間は返り値が変更されないためVSYNCで同期を 取らないと同じ入力状態を取得します。 VSYNC 1を入れるとボタンを押した瞬間だけ押した状態が 取得できるのはこのためです。
0そうだね
プレイ済み
返信[3]
親投稿
adarah adarah
レインさん ありがとうございます。 ボタン入力に疑問があったので、わざと続けて表示してみました。 otta777さん やっぱり、そういう事だったんですね。 VSYNC 1を入れない場合は、自分で処理を書く事にします。
0そうだね
プレイ済み
返信[4]
親投稿
スー thanks_0u0
説明の「ボタンを押した瞬間」の解釈が問題ですよね。 これが、本当に押したその刹那だけのことならプチコンさんは「押されたときに私はBUTTON命令以外を実行していたから、BUTTON命令のときには押された瞬間ではありませんでした」なんて言うかもしれませんが、それでは使い勝手が悪すぎます。 かと言ってプチコンさんは、瞬間の区切りをその場に合わせて人間に都合良く解釈するような柔軟性は持ち合わせていません。 そこでプチコンさんが一つの単位にしているのがシステム変数のMAINCNTです。VSYNCを挟まない場合、プチコンさんにとっての「瞬間」=MAINCNTが同じ間、に何回か命令が実行されてしまうので、プチコンさんは「MAINCNTが変わっていないからまだ押した瞬間だ!」と思ってしまうのだと思います( ´ ▽ ` )ノ
0そうだね
プレイ済み
返信[5]
親投稿
けい kei0baisoku
otta777さんの説明でほとんどですが、こう認識するとしっくり来ると思います、と言うのを少し補足させて頂きます。 BUTTON(2)の機能は「押された瞬間」ですが、これはもう少し厳密に表現すると「前回は押していなくて今回は押していたら」となります。 で、ここで「前回」と「今回」の定義は具体的になんぞや?ということになります。 連続的な時間をどこかで区切って定義してやる必要がありますが、ゲームだと時間はフレームで管理するのが一般的なので、プチコンでは「前のフレーム」「今のフレーム」で区切られています。言い換えると垂直同期のタイミングです。 なので、BUTON(2)は「前のフレームで押していなくて今のフレームで押していたら」になります。 垂直同期を待たずにボタン判定を取得すると結果が同じなのはこのためです。 ちなみに、これはBUTTON(0)でも同じそうです。
0そうだね
プレイ済み
返信[6]
親投稿
VSYNC 1以外ではうまく動かない命令・関数はほかにもあるかもね。
0そうだね
プレイ済み
返信[7]
親投稿
けい kei0baisoku
VSYNC(2以上)だと逆に、タイミングによっては押してもBUTTON(2)が反応しないそうですのでご注意下さい。 あと、特にプチコンがこの仕様にしている理由のくだりは、ゲームの一般的な常識などからの私の推察です。大きくずれてはないと思いますが、実際の理由と違ってましたらすみません。
0そうだね
プレイ済み
返信[8]
親投稿
BUTTON関数の振る舞いを確認するプログラムです。(KEY:4DK5KEF3) [管理者の方へ]問題があるようでしたら削除お願いします。 [使い方]実行を開始したら、数字が変わっている間にAボタンを押したり放したりしてください。3000になると結果の表示に移ります。↑と↓でデータを確認してください。 内容はプログラムから推測してください… [注意]BREPEATでリピート間隔を変更しています。
0そうだね
プレイ済み
返信[9]
親投稿
現在でも意味があるかどうかはわかりませんが、元は、ソフトウェアでチャッタリングを除去するためのものだったと思います。タイミングの時間は、チャッタリングの周期より十分長く、人間の動作より十分早い時間が設定されます。プチコンでは、けいさんのおっしゃるような理由で、フレームが適当と判断されたのでは無いでしょうか(推測)。そのため、フレーム内でON/OFFしたときは、検出できませんが、そんなに早く反応する人間はほとんどいないでしょう。
0そうだね
プレイ済み
返信[10]
親投稿
平たくいうとBUTTON(2)は 「ボタンが押下された、その1フレームの間だけ」 対応するビットが1になる、ということだと自分は理解しています。 人間の感覚からいえば1フレーム=1/60秒間は瞬間ではあるものの、プログラム的には結構長い時間なので、どうも直感的ではないですね。
1そうだね
プレイ済み
返信[11]
親投稿
確認プログラムは、あまりに不親切なので、わかった事を報告します。 (推測のため、今後仕様変更があるかもしれません。特に1項。) 1)プチコンは、フレームの最初に、物理ボタン(?)の状態を確認し、その状態を同一フレーム間保持する。 2)機能ID=0の時、1項の保持している状態を返す。 3)機能ID=2の時、前フレーム時の状態が0で、現フレームの状態が1の時、現フレームの間1を返す。 4)機能ID=1の時、3項に加え、押し続けているとBREPEATで指定した時間が経過する毎に、1フレームの間1を返す。 5)機能ID=3の時、機能ID2と逆に、前フレーム時の状態が1で、現フレームの状態が0の時、現フレームの間1を返す。 以上です。
0そうだね
プレイ済み
返信[12]
親投稿
スー thanks_0u0
気になって少しテストをしてみたのですが、ボタン押下の判定はフレーム(≒MAINCNT)の切り替えタイミングにあるみたいです。 フレームの中をVSYNCを使わずに、ループ+負荷でいくつかに分けてMAINCNTとBUTTONを記録するようなプログラムを実行したところ、毎回フレーム切り替え時からボタン押下となり、フレームの途中からボタン押下にはなりませんでした。 ですのでテスト方法に不備が無ければBUTTON(2)の範囲は、ボタンを押した次のフレーム切り替えタイミング〜その次のフレーム切り替えタイミング、なのだと思います。特に目新しい結果ではございませんが、一応書いておきますね(´ω`) あっ、私はコンピュータに詳しいわけではありませんので、意味や解釈などは他の方のものをご参考にされるのが良いと思います(*´∨`*)ノ
1そうだね
プレイ済み
返信[13]
親投稿
けい kei0baisoku
>コータさん、コア/co.aさん、スーさん 検証と分かりやすいまとめ、ありがとうございます。(投稿主でもないのにお礼を言うのはちょっと変かもしれませんが) 大変参考になります。 拝見した感じ、想像通りの挙動でした。 (3Dでない)DSのネイティブの仕組みはフレーム毎のサンプリング方式だったと聞いた覚えがうっすらあるので、多分プチコンもそれに準じてるのだろうと推測してます。 1/60秒未満の間にボタンを押して離してを正確に操作しないと検証できないので、確かめるのは高橋名人でも無理そうですが………
0そうだね
プレイ済み
返信[14]
親投稿
VSYNCの引数に、2以上の値を設定すると、ボタンが反応しないことがあるのは、同一フレーム内でON/OFFしたのと同様の効果があるためと思います。 なお、タッチ状態も、自分で同様の処理をすれば、タッチされたとき、離されたときの状態を取得することが出来そうです。
0そうだね
プレイ済み