コミュニティアイコン プチコン 非公式コミュニティ トピック

アバター
たらこ ◆pQb3ce9b/TEI
2019/4/2 17:57
質問
文字を表示させるやつ
RPGでよくあるポポポポポッってやつ
分かりますか?
文字を1文字ずつ表示させるやつです
あれってどうやって作るんですかね?

コメント

アバター
ツララ 2019/4/2 19:27 ◆ArUdBYOYME1V
>ナカジマさん
取っ掛かりとしてはクオリティが低い(個人的には全然そんな事無いと思いますけど)方が十分な仕事した事になるので、むしろOK!
いきなりヘビーなのが来て、後のコメントが全然付かない方が悲惨でしょ?
自分用で作るんじゃなければ、ガチガチなプログラムより
改良の余地が沢山あるユルユルなプログラムの方が、相手の事をちゃんと思って作ったんだなって感じしますよ。
少なくとも私がたらこさんの立場だったらそう受け取りますね。
アバター
初心者 2019/4/2 19:55 ◆ULvuffpmw1rp
ナカジマさんのプログラムは
粗悪なものではないと思いますよ。

ナカジマさんのプログラムのように、
文字列から一文字ずつ抽出して表示させるのがミソだと思います。
アバター
たらこ 2019/4/2 21:02 ◆pQb3ce9b/TEI
ナカジマさん
ありがとうございます
参考になりました!
アバター
たらこ 2019/4/2 21:06 ◆pQb3ce9b/TEI
初心者さん
ありがとうございます!
工夫は今後に生かしていけるので、
とてもありがたいです
Soybeanman さん
ありがとうございます!
あの、どこでエラーになるのでしょうか?
僕まだまだ初心者なので、エラーも出ることがたくさんあるのですが、理由がわからないことが多いので、教えていただけると嬉しいです
アバター
たらこ 2019/4/2 21:11 ◆pQb3ce9b/TEI
はやピーさん
あまさとしおんさん
ありがとうございます!
変数の宣言はVAR S$でOKですか?
同じ意味でDIM S$も良いですよね?
アバター
たらこ 2019/4/2 21:12 ◆pQb3ce9b/TEI
あと
外側の変数とはなんですか?
アバター
たらこ 2019/4/2 21:15 ◆pQb3ce9b/TEI
ツララさん
初心者さん
そうですね
本当にいろいろなことに気づいて、今後に活かせる知識が増えたので、良かったです
アバター
ナカジマ 2019/4/2 21:52 ◆DSpvksQCyRZC
コメント欄があったかい……
アバター
Soybeanman 2019/4/3 9:19 ◆SDLkyXUP6WqK
>>たらこさん
もし変数Iが、0未満もしくは文字列の長さ超過の場合、[]の中身(添え字といいます)が、正常な値を引き出せなくなる為エラーになります。
逆にMID$の場合はエラーになりません。
これはよくわからないのですが、恐らく例外処理を組まなくていいようにというSmileBASIC製作陣の優しさからこの様な仕様になったのだと予想します。
アバター
たんじぇ 2019/4/3 12:23 ◆WDmFkVwZ4yMl
MID$は「配列」ではなく「文字列」を扱う関数なのです。
文字列操作系の関数は文字列の長さを超えた値を渡されてもエラーが発生することなく動作するようになっています。

今回のように文字列を分解して1文字ずつ処理するのであれば本来はMID$を使うのがプログラムとしては正しいです。
(作りたい処理は「文字列を1文字ずつ表示して音を鳴らす」で文字列を分解するのはMID$関数)

ただし文字列は配列として扱えるし、書き方によっては処理が早かったりコードが見た目すっきりするなど、BASIC特有の理由があるのであれば配列にしても動きます。


なお配列で要素数を超えてアクセスしてエラーになることについては、アクセスする前段階でその要素数を超えないことを範囲チェックなどで保証する必要があります。

たとえば、今回の話の流れではLENで配列長だけループしているので絶対に要素範囲の範囲外はアクセスしません。
ただし今後処理を追加していって改行コードチェックなどで要素+1の配列をアクセスするような処理を追加する場合、LENの長さチェックだけではエラーが起きる場合があります。
こういった場合にどうするかは追加する内容によりけりですが、文字列の最後に空文字を追加する、そもそも要素+1でチェックしないなどやりかたはいろいろあります。

配列アクセスの基本は、必ず要素範囲内かどうかチェックするです。
特に自由に要素数を入力できたり、要素数を超えるかも知れない計算結果で配列要素をアクセスするなら範囲チェックは必要です。
アバター
たんじぇ 2019/4/3 12:28 ◆WDmFkVwZ4yMl
ちなみに

FOR (略) TO LEN(S$)-1



LEN(S$) を毎回計算する言語もあったりするので使う場合は少し気にしておく必要があるかもしれません。

たとえばループ中でS$の長さが変化した場合、SmileBASICでは正しく動くかどうか知っておいた方がいいかもしれません。
アバター
まるだい 2019/4/3 18:34 ◆AdwyE6qhnxpV
VSYNCじゃなくて
WAITのほうがいいですよ〜
VSYNCだと最初の二文字が同時(一回目のVSYNCが無視される)になっちゃうので
アバター
あまさとしおん 2019/4/3 19:02 ◆mzDKTVUAtwqE
変数には『スコープ』(有効範囲)があるのです。
プチコンの場合は、2種類で
ローカル変数 と グローバル変数(厳密にはスロット内のローカルだが) があります。
グローバル変数は「1つのプログラムスロットの中で、どこでも使える変数」です。
ローカル変数は「1つのDEFの中だけで使える変数」です。

DEF〜ENDの間に変数宣言をすると、ローカル変数になり
それ以外の場所で変数宣言すると、グローバル変数になるのです

通常、同じ名前の変数は1回しか宣言できませんが、
グローバル変数とローカル変数の場合は、そうならないのです。
この場合「ローカル変数で使われてる名前なら、ローカル変数を処理する、違うなら、グローバル変数として処理する」となります。


って、日本語が難しくなってきましたね

(続き)で実際にプログラム例を書くので、それを見たほうが分かりやすそうです
アバター
あまさとしおん 2019/4/3 19:10 ◆mzDKTVUAtwqE
(続き)
実際にスコープを使い分けるプログラムです
(サンプルなので特に意味はないです)

VAR I=200
TEST_
PRINT I

DEF TEST_
 VAR I
 FOR I=1 TO 10
  ?I
 NEXT
END

グローバル変数の「I」を宣言した後に「TEST_」というDEFを呼び出しています。
「TEST_」の中で1から10まで変数「I」を書き換えているのに、最後に「200」と表示されます。
なぜか、というと「TEST_」の中で使ってる「I」はローカル変数だからです。

試しにDEFの次の行の変数宣言を消してから実行すると、最後に「11」と表示されるはずです。

このようにDEFで使う変数をローカル変数にすると「うっかりDEFの外側の変数を変えてしまった」という事故を防ぐことができます。
アバター
あまさとしおん 2019/4/3 19:11 ◆mzDKTVUAtwqE
なお、変数宣言をする命令はVAR、DIMどちらを使っても大丈夫です。
アバター
あまさとしおん 2019/4/3 19:25 ◆mzDKTVUAtwqE
サンプルコードの中で

VAR I=200

と書いていますがこれは

VAR I
I=200

と同じ意味合いです。
変数宣言するときに代入も同時にできる、という豆知識。
アバター
オワたず 2019/4/5 1:04 ◆w7BXxYlkW2NJ
waitだとプログラム全体が影響を受けるので、私はカウント用の変数を用意して、ループ内で加算させて行って数値がある一定に達したらifで文字を一つ表示して、変数をリセットするという手法を取っているけどこれってどうなんでしょ
アバター
Godot 2019/4/6 13:03 ◆ULYW1MrfcSYD
こんな感じても。

参考まで。
アバター
たんじぇ 2019/4/10 12:28 ◆WDmFkVwZ4yMl
WAITは指定したフレーム(1/60秒)待つ関数。
VSYNCは前回実行したVSYNCから指定したフレーム(1/60秒)過ぎるまで待つ関数。
と、微妙な動きの違いがあります。

VSYNCが1回も実行されていない場合はどうなるか動作不明(おそらく実行開始時にVSYNCが実行されたように動作する)なので、 VSYNCを使うループ開始の直前で1回 VSYNCを入れておくときれいに動作します。



WAIT, VSYNCを使わずにカウンタ変数を使って実現する場合、メインのループから呼ばれて1フレーム(1/60秒)ごとに1回よばれるようなつくりにすることができ、
音を出して1文字ずつメッセージを表示しながら、他の処理ができるようになります(たとえばメッセージ表示中にNPCが動いたりとか、メッセージに関係ない他の処理とか)

この場合、メインループから1フレームに1回だけ呼ばれて処理するため、そのように動作するようなつくりが必要になります。
メッセージ表示にたとえば2秒(120フレーム)かかるなら、メッセージ表示処理が 120回呼ばれるようになります。

表示開始から何フレーム目か、何文字目まで表示完了しているか、呼び元でもうこの処理を呼び出す必要があるかどうか(全部表示したかどうか)などの変数を元に、処理が1回呼ばれたら何もしないのか、文字表示など何か処理するのかを判断するようになります。


アクションゲームなどで敵が勝手に動くようなしくみも、これと同じような作りになっています。
アバター
はやピー3DS 2019/4/13 8:25 ◆cNXcKm243Rna
Godotさんのを改造して一行に表示するようにしました!

コメントを書く

  • こちらは「プチコン3号」「プチコンBIG」など、プチコンシリーズに関する話題を扱ったコミュニティです
  • プチコンシリーズにまったく関係ない書き込みはご遠慮下さい。削除の対象となります
  • こちらにはその他のゲームや雑談のコミュニティはなく、作る予定もありません (ひとりで管理できないため)。ごめんなさい
  • ユーザー登録なしで書き込みができます
  • 秘密の合い言葉は成りすましの防止 (トリップ機能)、書き込みの編集時の本人認証に使用します
  • 秘密の合い言葉に他人に推測されやすい言葉、他サービスと同じパスワードは入力しないでください。
  • 書き込むと、投稿時に入力したお名前と秘密の暗号が記憶され、ログイン状態になります

- WEB PATIO -