見出し画像

[ティラノスクリプト]簡易ループ(foreachっぽい)書き方

はじめに

ループ研究の2回目ですw
前回はループ回数を指定するループでしたが、今回は、何個あるか分からないけど、個数分ループさせたい場合に使うforeachです。
といっても偽物です。foreachっぽいことも出来るよってことですね。

ただし、前回のやり方がベースになっているので、必要でしたら、こちらも参考にしてみてください。


foreachループ

そもそも、foreachとはなんぞや? って方は以下をどうぞ。
超簡単にいうと、データを持ってる分だけループします!! 感じです。

まずはソース

今回も、とりあえず先にソースを貼ってから説明します。
前回より少しだけ長目ですが、これはループさせるデータを作っている箇所があるからです。

;JavaScript
@iscript

    // イメージ配列の作成
    // ※配列なので変数名を複数形にしておくと分かりやすい
    tf.images = [
        {file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'},
        {file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'},
        {file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんは'}
    ]

@endscript

; イメージ配列の作成
; ※これでも上記と同様に配列作成を行えるが、evalタグだと1行でしか書けないため、横長になって見にくい
;@eval exp="tf.images = [{file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'}, {file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'}, {file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんわ'}]"

; ループ用カウンタの初期化
; 配列のインデックスは0から始まるので0を設定しておく
@eval exp="tf.index=0"

; ループ開始
*do_while_index

    ; 配列内のオブジェクトを取得
    @eval exp="tf.image = tf.images[tf.index]"

    ; イメージ表示
    @image layer="0" storage="&tf.image.file" x="&tf.image.x" y="&tf.image.y" width="32" height="40"

    ; メッセージ表示
    @ptext layer="0" x="&tf.image.x" y="&tf.image.y + 40" text="&tf.image.message"

; ループ終了
; ※条件判断に配列の個数を利用する
@jump target="*do_while_index" cond="++tf.index < tf.images.length"

; 一時変数の削除
@clearvar exp="tf.images"
@clearvar exp="tf.image"
@clearvar exp="tf.index"

ちなみに、このサンプルは、配列に入っている3つ分のデータ(オブジェクト)を表示させています。

①データ作成

;JavaScript
@iscript

// イメージ配列の作成
// ※配列なので変数名を複数形にしておくと分かりやすい
tf.images = [
{file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'},
{file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'},
{file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんは'}
]

@endscript

いきなりJavaScriptですが大丈夫です。たいしたことはしていませんw
ここでは、今回表示したいイメージのデータを作成しています。

一時変数(tf)に「images」という配列を作成して、その中にデータ(オブジェクト)を3つほど追加しています。

そのデータ(オブジェクト)の中身ですが、これには4項目ほど設定しています。

1つ目は、「file」です。
ここは、表示するイメージのファイル名を設定しています。

2つ目は、「x」です。
これは、表示するイメージのX座標を設定しています。

3つ目は、「y」です。
これは、表示するイメージのY座標を設定しています。

最後に4つ目は、「message」です。
これは、表示するイメージの下に一言表示するメッセージを設定しています。

と言うことで、オブジェクトは、中括弧({…})で囲んだ中に、設定したい項目名と、設定する値をコロン(:)で区切ってペアにし、そしてそれを必要な分だけカンマ区切りで並べてあげれば、作成する事ができます。

{ 項目名1 : 値1 , 項目名2 : 値2 , …… , 項目名n : 値n }

オブジェクトの書き方

今回は、このデータを3つ分作っているので、tf.images変数の中身は以下となっています。

tf.images[0]={file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'}
tf.images[1]={file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'}
tf.images[2]={file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんは'}

また、次の行は、JavaScriptではなく、evalタグを使用した場合のデータ作成方法です。

; イメージ配列の作成
; ※これでも上記と同様に配列作成を行えるが、evalタグだと1行でしか書けないため、横長になって見にくい
;@eval exp="tf.images = [{file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'}, {file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'}, {file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんわ'}]"

どちらでも同じ事が出来るのですが、evalタグでは改行ができないため可読性が落ちてしまいます。
なので、今回はコメントアウトして使用しないようにしています。
こういうかたちでも、書けますよというサンプルです。

②カウンタの初期化

; ループ用カウンタの初期化
; 配列のインデックスは0から始まるので0を設定しておく
@eval exp="tf.index=0"

ループ回数をカウントする変数を作ります。
一時変数(tf)に「index」と言う名前の変数を作成して、そこに初期値として、0を代入しています。
配列は0から始まるので、初期値は0にしておきます。

③ループ開始

*do_while_index

ここは、ただのラベルです。
後ほど説明する、jumpで戻って来る場所になります。

④データ(オブジェクト)取得

; 配列内のオブジェクトを取得
@eval exp="tf.image = tf.images[tf.index]"

ここが、foreachっぽくするためのキモですね!
なにをやっているかというと、配列に入っているデータ(オブジェクト)を取得しています。

まず、一回目のループでは、「tf.index」にはが入っていますね。
なので……
「@eval exp="tf.image = tf.images[tf.index]"」は
「@eval exp="tf.image = tf.images[0]"」になりますね。

そして、「tf.images[0]」には、
{file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'}
が入っていますので、この処理で、「tf.image」変数に
{file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'}
が入ることになります。

同様にループの2回目ですと、「tf.index」にはが入り
tf.images[1]には、
{file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'}
が入っています。
なので、tf.imageには、これが入りますね。

この、0、1、2と変動する部分に、カウンタを使用することで、順繰りにデータ(オブジェクト)を取得することができます。

⑤イメージ表示

; イメージ表示
@image layer="0" storage="&tf.image.file" x="&tf.image.x" y="&tf.image.y" width="32" height="40"

ここでは、上記で取得で「tf.image」変数を利用してイメージを表示しています。
tf.image」には、オブジェクトが入っているので、これを参照します。

オブジェクトの参照は、「.項目名」で行えます。
ループの一回目ですと「&tf.image.file」には「'chara/holocco_ds.png'」が入っており、同様に「&tf.image.x」は「100」、「&tf.image.y」も「100」、そして「&tf.image.message」には「'おはよう'」と入っています。

⑥メッセージ表示

; メッセージ表示
@ptext layer="0" x="&tf.image.x" y="&tf.image.y + 40" text="&tf.image.message"

ここは、イメージ表示とほぼ同じです。
&tf.image.message」に入っているメッセージを、ptextタグで表示しているだけです。

⑦ループ終了

; ループ終了
; ※条件判断に配列の個数を利用する
@jump target="*do_while_index" cond="++tf.index < tf.images.length"

基本的には、ただのjumpです。なので、ループ開始の際に定義した*do_while_indexへジャンプします。
ただし、この条件が、前回の簡易ループと少し異なります。

cond="++tf.index < tf.images.length"の部分ですが、ここに、配列の個数を利用しています。tf.images.lengthの部分です。
これはJavaScriptのメソッドで、配列の要素数(個数)を返してくれます。

①のデータ作成で作成したデータは、下記になってますね。
tf.images[0]={file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'}
tf.images[1]={file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'}
tf.images[2]={file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんは'}
なので、データは3個(3行)あることになります。

したがって、tf.images.lengthになりますね。
ということは……
cond="++tf.index < tf.images.length"」は、
cond="++tf.index < 3"」と言う意味になります。

そして、一回目のループでは、tf.indexですので、
これに++で1を加算した結果は、1になり、「cond="1 < 3"」が成り立ち、ループ開始位置にジャンプすることになります。

この仕組みを利用し、データを作成した分だけループを実行します。

⑦使用した一時変数の削除

; 一時変数の削除
@clearvar exp="tf.images"
@clearvar exp="tf.image"
@clearvar exp="tf.index"

今回は、配列(tf.images)、配列の中身を取得したもの(tf.image)、そして、カウンタとして利用したもの(tf.index)の3つ変数を削除します。
前回も書きましたが、自分で使用したものは、自分でお片付けの精神ですw

実行結果

さて、上記のスクリプトを実行した結果です。
表示されているキャラは、現在制作しているものを流用しただけですので、あまり気にしないで下さいw
表示位置やメッセージなどが、データ作成の通りに表示されていればOKです!!

実行結果

foreachループの利便性

データの個数分ループすることの利便性を少し追記して終わりにしたいと思います。

データ操作

「①データ作成」で作成したデータに、2行分追加しました。

;JavaScript
@iscript

// イメージ配列の作成
// ※配列なので変数名を複数形にしておくと分かりやすい
tf.images = [
{file: 'chara/holocco_ds.png', x: 100, y: 100, message: 'おはよう'},
{file: 'chara/jacyus_ds.png', x: 200, y: 200, message: 'こんにちは'},
{file: 'chara/skuri_ds.png', x: 300, y: 300, message: 'こんばんは'},
{file: 'chara/jacyus_ds.png', x: 400, y: 200, message: '追加その1'},
{file: 'chara/holocco_ds.png', x: 500, y: 100, message: '追加その2'}

]

@endscript

この状態で、他の部分は何も変更せずに、スクリプトを実行します。

データ追加後の実行結果

すると、上記のように表示されます。
データの個数分ループするので、スクリプトを何も変更せずとも表示内容を増やすことができました。
作成するデータを操作することで、論理的には、100でも200でも追加することができます。
これが、foreachの利点だと思っていますので、それなりに利用機会もあるのかな? と思っています。

おわりに

1年後の自分に向けて、かなり細かく書いていますw
忘れた頃に見ても、これなら思い出せるのでは?
また、同じようなことをやりたい方に、少しでも参考になれば幸いです。
ではでは。


この記事が気に入ったらサポートをしてみませんか?