プレイ日記
ネタバレ
ばいし madanai2nd
プレイ日記。 この自作のプログラムでは、on ~ gotoの使い方を学びました。 顔文字を自動的に変化させながら十字ボタンで移動できるところが目標だったのですがそこまではいきませんでした。勝手に顔が変化し、勝手に動きます。 print文の点滅の質問が参考になりそうだと思うもののなかなか理解が追いつきません。 button()を使う時、wait(120とか)やvsyncを使って入力が効かなかったのですが、 repeat,wait 1,until button()!=0だかを使ってまた改善してみます。 思った通りに動かない~。 長いのでネタバレにした方がいいのかな? では。
3そうだね
プレイ済み
返信[1]
親投稿
だにえる haru2016nen
そのON GOTOの部分、 GOTO"@F"+STR$(A+1) と略せます! あと、PRINTは「?」で代用出来るので PRINT "A" ↓ ?"A" と、出来ちゃいます!
0そうだね
プレイ済み
返信[2]
親投稿
ばいし madanai2nd
"数値から文字列を得る"ですか、まだ使っていませんでした。ラベルの名前にするために使うのですね。 printは"?"で使ったことあります。分かりやすい範囲でできるだけ省略するのがよいようですね。?も使ってみます。 少しずつ勉強させていただきます。 ありがとうございました。
1そうだね
プレイ済み
返信[3]
親投稿
見えてある範囲のプログラムではボタンの処理がないのでランダムに動く(ボタン関係ない)というのは、そういう動作のプログラムに見えますね。 具体的にどうしたいかを書きつつ、その付近のプログラムを載せる(もしくは公開キーを出す)と色々とアドバイスがもらえるかもって思います。
0そうだね
プレイ済み
返信[4]
親投稿
ばいし madanai2nd
実験的にできそうなことをいろいろやっていこうと思って、今回は某魚人間のソフトやペットを飼うソフト、育成ソフトのように勝手に動いているけど干渉もできるプログラムを目指し、うまくいかずボタン操作の部分を削って載せました。 たしかにうまくいかない情報が見れないとアドバイスしにくいですよね。現状、ランダムで動くものはできているので、後で公開キーを載せるかもしれません。質問はまた改良中に詰まったら問題が具体的になるのでしようかなとも思っています。
1そうだね
プレイ済み
返信[5]
親投稿
キャラクターを動かしながらカーソルを動かしたい、などの場合、23行目や25行目のように長時間のVSYNC(WAIT)を使ってしまうと、そこで動きが止まってしまうので希望通りの動作にならないと思います。 なので基本全ての処理を平行して動くように工夫する必要があります。そうするとメインループの中は基本的にはVSYNC(1/60)のみになって、それ以外でVSYNCやWAITで止めることはほとんどしません。(処理が一時的に止まっても問題ない時を除いて) おそらく今までボタンの処理がうまくいかないと感じているのはその辺が関係あるんじゃないかと思います。
0そうだね
プレイ済み
返信[6]
親投稿
ツララ LongIceSword
多分これ@MYC~RETURNでサブルーチンになってますよね? GOSUB命令で飛んだ先でまたGOSUB命令を使っても別に問題は無いので(FOR~NEXT等の多重ループと同じで、対応するRETURN命令に戻って来れれば大丈夫) @F1や@F2とかの分岐先の処理が表示パターンの種類分けなら、分岐先もサブルーチンで書いておいて、表示時間カウント用の変数(例:T_CT)とIF文を使えば @MYC (XとYの移動処理は割愛) T_CT=(T_CT+1) MOD 240 IF T_CT==0 THEN A=RND(13) ON A GOSUB @F1,@F2,~,@F13 RETURN @F1 LOCATE X1,Y1:?"     ":LOCATE X1,Y1 IF T_CT<120 THEN ?"(・v・)" ELSE ? "(・o・)" RETURN @F2 ・・・
0そうだね
プレイ済み
返信[7]
親投稿
ばいし madanai2nd
>でんぺんさん 表示が速すぎたりfor nextで繰り返し書いたりしたのちvsync 120を試しました。vsyncは基本、1のようですね。その方向でまた試そうと思います。 >ツララさん gosubの入れ子が可能なのは理解できました。時間のカウントの制御はまたこちらで実験などしてみます。if文の前の文の理解もまだ必要です。
0そうだね
プレイ済み
返信[8]
親投稿
ツララ LongIceSword
A=A+1 っていう処理を繰り返すと、変数Aの中身が0,1,2,3,…という感じに増えて行くのの理解は大丈夫です? MODは余剰(割り算した時の余り)を出す演算子で、例えば A=(A+1) MOD 16 っていう処理だと変数Aの中身が16を越えない数(0~15)でグルグル回る感じになります。 もし配列変数の使い方にも慣れたなら、顔文字は文字列変数の配列に予め用意しておいたり 顔文字を消すのも、空白を文字数分入れた文字列変数を用意しておいたりすれば便利ですよ。 ちなみに FOR TIM=0 TO TIM STEP 1  TIM=TIM MOD 360  ー 処理 ー  VSYNC 1 NEXT みたく書くとVSYNCが60回分で約1秒なので、処理が1フレーム以内で収まるなら約1分で変数TIMの中身が一巡する感じのラベルジャンプじゃない無限ループも作れますよ。
0そうだね
プレイ済み
返信[9]
親投稿
ばいし madanai2nd
>ツララさん if文の前の文はカウンターを回すようなイメージですか。0の時に顔を選んでカウンターの前半と後半で顔を分ける、と。ふむふむ。理解できてきました。配列は使い始めたものの、まだ慣れてはいません。 理解ができていない間に独自に変更したところ(顔1の時)動いたので教えていただいたものも打ち込んで比較してみようと思います。ありがとうございます。 写真は修正後動いたもののリストの一部です。 何秒たったらという判断も疑問に思っていたので参考にさせていただきます。
1そうだね
プレイ済み
返信[10]
親投稿
今のプログラムでは、16〜19行は実行されないデットコードになっていますが、その辺ってわかってますか? プログラムの流れを理解してないとなかなか動作のイメージが掴みづらいだろうと思ったので…。 変更したプログラムも並列動作させるプログラムとしては、ちょっと微妙な部分もあるんで悩ましい感じもありますね。まあでもとりあえず目的通りに動いたのならいいのかな…。 並列的なプログラムのイメージはパラパラ漫画を作るのにも近いです。1フレーム(VSYNC)の間に1コマの絵を作ります。3つの物を動かすとしたら3つが1コマだけ動いた状態にするわけです。ウエイトをしたい場合は、しばらく動かさない(変更しない)という感じにして60コマ目に動かせば(VSYNCは1/60なので)1秒後に動くプログラムに見えるわけです。 という感じではありますが、少しずつ動かして理解を深めていく感じだと思います。
0そうだね
プレイ済み
返信[11]
親投稿
ばいし madanai2nd
テッドコードになっていたんですね。分かりませんでした。と、いうか、画面外に出てしまったことから@idouのラベルに修正(コピー)して、、、あ、移動させた時の消し残しのようです。消しておきます。 パラパラマンガのイメージですか。その感覚も分からなかったので参考になりました。自分は時間軸で長い間いろいろさせようとしすぎの感覚かもしれません。 参考になりました。
0そうだね
プレイ済み
返信[12]
親投稿
プログラムの見えない部分(上の方)がわからないので正確にはわからないのですが、プログラムの流れを頭から追ってみるといいと思います。 そうすると必ず15行目のGOTOで別の場所に飛びます。それで、その別の場所からはGOTOで@MYCに飛ぶ(戻る)ような動作になっていますが、そうなると16行目から下にプログラムが流れることがないことになりますよね。 (ラベルのある21行目から下はGOTOなどで飛ぶので流れる可能性がありますし、実際に流れてますが) という感じで見ていくとデットコードになっているのに気づけると思います。 ばいしさんはまだプログラムの流れの一部で処理をしようとし過ぎている印象がありますね。なので、その流れの一部で処理が止まる(ループ)してしまって、他の部分が動作が並列して動かせないわけです。 なので、全体を大きな流れとしてとらえられるようになるといいですね。
0そうだね
プレイ済み
返信[13]
親投稿
大きな流れとしては、 メインループ {  ・ボタンなどの処理  ・カーソルの処理(表示含む)  ・顔文字の処理(表示含む)  ・VSYNC(ここで1枚の絵が表示されるイメージ) } という感じです。そして各処理の間ではWAIT(やVSYNC)を入れないのがポイントです。あくまで表示タイミングはメインループ最後のVSYNCに一括して任せて、それまでは1コマの絵(1フレーム)の画面を作るだけの処理にする感じです。 そうすると必然的にタイミングや状態を管理する為の変数が増えることになったりもしますが、その辺はいずれどちらにしても必要になってくる事なので、試しながら覚えておくといいと思いますよ。
0そうだね
プレイ済み
返信[14]
親投稿
ばいし madanai2nd
while~wendなどのメインループをパラパラマンガの紙の集まりのように見て、gosubなどで各処理に分担させて一枚ずつ描いていくような感じになりますか。考え方の違いはつかめました。 全体を見るのは大切なのだと思います。今はできることをつけ足しで作っているので全体から見たものも練習するようですね。本当はフローチャートのようなものも作るのがいいのかもしれません。 写真は先程載せようとした移動の部分のプログラムです。掲載ミス失礼しました。
0そうだね
プレイ済み
返信[15]
親投稿
なんとなくでも分散のイメージが掴めたのなら良かったです。 今はまだVSYNCやWAITの数値による制御が多いですが、その辺は経験で減らせていければ良いんじゃないかと思います。 あと必ずしもそうしないといけないというわけではなくて、必要に応じては部分的な処理(ループ)で画面の一部だけ更新するような場合もあります。(平行動作させる必要がない部分的な演出など) なのでケースバイケースですが、複数のオブジェクトを同時に動かす際には、この平行動作の考え方は出てくると思うので、少しずつ覚えて使っていけるようになればいいなと思います。 ちなみに複数のオブジェクトを同時に動かすようになると配列などの出番も増えます。 という感じですが、これからも頑張ってください!
0そうだね
プレイ済み
返信[16]
親投稿
ばいし madanai2nd
処理を分散させる時に配列の重要性も上がってくるのですね。 パラパラマンガ作成のような分散のイメージも使ってみようと思います。 ありがとうございました。
0そうだね
プレイ済み
返信[17]
親投稿
ツララ LongIceSword
パラパラ漫画のイメージが掴めてるなら、今は何コマ目なのかが分かるような変数を作っておけばプログラムの流れを把握しやすいですよ。 その変数依存で色んな処理をさせれば、VSYNCやWAITは単にプログラムの回転スピードを調節するだけの役割を任せるだけで済みますから。 FOR文でメインループを作る利点は、FOR文は構文中でカウンタ変数を設定するのがデフォルトで、その変数がまさにパラパラ漫画の今何コマ目かを示してるので、動きをコマ数で管理したい時とかに便利だったりするところですかね。 あとカウンタ変数で管理する利点としては、IF文でサブルーチンに飛ぶ時に、カウンタ変数がこの値からあの値の間だけ実行するサブルーチンとかやるとマルチスレッドの概念が理解しやすいかもとかですね。
0そうだね
プレイ済み
返信[18]
親投稿
ばいし madanai2nd
パラパラマンガとfor文とカウンタ変数が繋がってきてほうほう、なるほどといった感覚です。 while~wendの方がざっくりなんでも使えるような気がしたのですがfor文のカウントできるメリットはたしかに大きそうです。 ありがとうございました。
0そうだね
プレイ済み
返信[19]
親投稿
ツララ LongIceSword
WHILE~WENDのメリットは、ループの終了条件を頭の方に書くことでループ自体がIF文と同じように、条件に合致しない場合は丸々ループをスキップ出来たりすることですかね。 命令それぞれにそれぞれのちゃんとした利点が有るので、慣れてくればばいしさんもちゃんと使い分け出来る様になりますよ。
0そうだね
プレイ済み
返信[20]
親投稿
ばいし madanai2nd
命令の利点までふまえて使いわけられればすごいですね。各コマンドを使い慣れるにはたどり着けても先の長い話ではありますが。使わないことには慣れないので少しずつ分かる範囲を広げていければとも思います。
0そうだね
プレイ済み
返信[21]
親投稿
ツララさんのFORはちょっと特殊なやり方の部類ですね。(終了条件によるFORによるカウンタ処理) ただ覚えておくと便利なところもあるかも。 使い分けという面では、WHILEとREPEATがあると思います。両方とも条件によるループですがREPEATの場合は必ず1回は実行される差があります。 通常はWHILEで考えると思いますが、場合によってはREPEATの方が適しているケースもあったりして、そういう場合は使い分けられるようになると便利だったりしますね。 それに使い分けといってもループ系は、GOTO(プログラムに慣れたら非推奨?)、FOR、WHILE、REPEATの4種類ぐらいじゃないかとも思うので、それほど難しくもないですから、少しずつ使ってみるといいと思いますよ。
0そうだね
プレイ済み
返信[22]
親投稿
ばいし madanai2nd
ピックアップして4種類と言われると確かに少ない感じがしますね。慣れれば使い分けられそうな気がしてきました。自分はforとrepeatが使い慣れていないことも感じたので、慣れていければと思いました。
0そうだね
プレイ済み
返信[23]
親投稿
ばいしさんの覚えようとする姿勢はとても良いと思いますし上達すると思いますよ! ちなみにWHILEとREPEATの使い分けで僕が意識的によく使うのはボタン待ちの時ですね。たとえばAボタンを押すまでループさせる場合、 WHILE BUTTON(2)!=#A:WAIT:WEND と REPEAT:WAIT:UNTIL BUTTON(2)==#A の2通りの書き方があります。一見同じような処理に見えますが、実はこの場合は下のケースの方がよりベストだったりします。 理由はBUTTON命令はVSYNC(やWAIT)のタイミングでボタン情報が更新されます。なので上のケースだとボタン情報が更新される前の状態でチェックされてWHILEが実行されない(正確にはすぐ抜けてしまう)という状態になる可能性が残ってます。 下のケースの場合、必ずWAITを通ってから判定がはいります。
0そうだね
プレイ済み
返信[24]
親投稿
ばいし madanai2nd
repeatは必ず一回は実行される、というのが違いとして出てくる部分のようですね。 微妙すぎてまだ自分で判断できる気はしませんが。慣れが必要なのでまた練習のプログラムも考えたいところです。 練習作の公開キーが出たので新しい日記に出せれば出す予定です。
0そうだね
プレイ済み
返信[25]
親投稿
正直、僕もREPEATを使う機会はそんなに多くはないです。通常のループであれば、プログラムを頭から読んだときに終了条件がすぐ目に付くWHILEの方を使います。 なので頭の中でそんなのがあると覚えておいて、もし1回は実行して欲しいみたいなケースが発生したときに、そういえば!って感じで思い出せればいいと思いますよ。 ということで、なんだかんだで色々と話が飛んでしまった気もしますが、これからも頑張ってください!
0そうだね
プレイ済み
返信[26]
親投稿
ばいし madanai2nd
ありがとうございます。 ちょうど日記を更新して、公開キーを載せました。気が向いたらお試しください。ではでは。
1そうだね
プレイ済み
返信[27]
親投稿
ツララ LongIceSword
ON GOTOでもループ作れますよ。 というかラベルと組み合わせれば、プログラムの流れを変える命令なら全部ループを作るの可能ですよ。 例えば @LOOP ー 処理 ー IF !A THEN @LOOP と書くと(Aは任意の変数)簡易的なREPEAT~UNTILの代わりになりますし。 あと、顔文字が時間経過で自動的に変化しながら、且つ十字キーでの操作に対応させるのが当面の目標だったんですよね? VSYNCで時間経過を処理すると、そこで一切の処理が待ち状態になるので、当然ながらBUTTON()関数での入力も処理されないですよね? それを回避するならループの種類は関係無しに擬似タイマーとして使えるループ数をカウントする変数を組み込んで、その変数とIF文で顔文字の表示を制御すればいいと思うんですけど、なぜカウンタ変数に触れずシステム変数のMAINCNTに付いても言及しないのか
0そうだね
プレイ済み
返信[28]
親投稿
ばいし madanai2nd
>ツララさん 試行錯誤でたまたまなのですが、for nextを使うことで顔を変えつつの入力は達成できました。最新のバージョンではないですが、公開キーは【9348Q5KX】です。今日はXボタンに機能の割り当てをしました。 コメントありがとうございました。
0そうだね
プレイ済み
返信[29]
親投稿
僕はON GOTOやIF でのGOTO省略はGOTOカテゴリーに含めてしまいましたねー…。 MAINCNTについて説明しないのも始めにFORによるカウンタ変数を使っていたので、まずはカウンタ変数でのやり方を覚えるのかなと思ってました。 あとはまあ一度に詰め込みすぎると混乱しそうだというのもあったんですけどね。
0そうだね
プレイ済み
返信[30]
親投稿
ばいし madanai2nd
カウンタ変数という考え方を知らなかったこともあり、for nextを使ったのは時間調整のための(試行錯誤による)たまたまの部類でした。パラパラマンガの考え方を聞き、少しかみあってはきていますが、まだ一枚分の作り方の把握もできていない段階です。 少しずつ頑張ります~。
0そうだね
プレイ済み