今回は「配列変数」の話をします。 配列変数は「HSP以外の言語でも当たり前のように出現する重要なもの」ですので、是非とも覚えましょう。 「配列変数」とは、同じデータ型を並べた変数の塊のことです。 データ型は、変数の扱える値のタイプ(数値や文字等)や、表現範囲が決められた、まさに「型」のことで、 HSP3では、数値型・実数型・文字列型・ラベル型・COMオブジェクト型と言ったものが用意されており、 同じ型が連続して幾つも使える変数群が●●型配列変数です(●●には上記の型名が入ります)。 …と、言葉の説明だけでは少し内容が難しいので噛み砕いてみましょう。 変数には、1つの値や文字列等だけを入れることができましたね。 「1」という値を入れたり「ABC」という文字列を入れたり…。 もし「-5」「100」の2つを同時に持たせたいなら、2つの変数、例えば変数Aと変数Bを使う必要があります。 10個を同時に使う場合は変数10個、100個なら変数100個…と、その数分の変数が必要です。 ツール系ソフトでは、同時に大量の変数を扱うことは少ないかもしれませんが、 ゲームではパズルやアクション等のジャンルを問わず、幾つもの値を同時に保持しなければなりません。 HSP2講座同様にイメージしやすく、膨大な数を保持するシューティングゲームを例にしてみます。 自機を縦横自在に動けるようにするには、X座標・Y座標の2つの情報を保持することになります。 自機だけしか出現しないシューティングゲームはほとんど見ませんね。 敵も画面上に出現し、自機とは別の位置に出現して異なる動きをしますので、 敵用にもX座標・Y座標の2つが必要になります。 敵は同時に複数出現することがありますので、敵数×2が必要になります。 シューティングと言うくらいですので、弾で敵を打ち落とす(シュート)行為が出てきます。 弾も敵に当たるまで、位置情報を保持している必要があり、複数の弾が必要なら複数の変数が必要です。 …さて、コレだけで幾つの変数が必要になったでしょうか? 変数jiki_x、jiki_y、tama_x1、tama_y1、teki_x1、teki_y1、tama_x2、tama_y2、teki_x2、teki_y2… 弾や敵など複数同時に発生した場合、全く同じ位置・同じ動きはないにしろ、 特に弾なんかはある程度同じ動きをするということがよくあります。 それなのに別々の変数である為に、前の章で覚えていただいた繰り返し命令が全く役に立ちません。 全部の弾に対して同じ様に値を入れていかなければならないから、です。 現在使われているのがどれで、今回操作するのがどの変数か、管理が非常に難しくなりますね。 長々と説明しましたが、こういったときに役立つのが配列変数なのです。 配列変数は、数値と文字列を混合することはできませんが幾つもの値を保持することが可能です。 数値は数値でも、整数と実数は別物ですので混ぜられません。 「1つに複数保持できる」と言うのは少し語弊がある為に補足しておきますが、 厳密には1つの配列変数には複数の変数が入ったイメージで、 配列変数内のそれぞれの入物「要素」には1つの値しか保持できませんが、 1つの配列変数としては複数の値を保持できると言うことです。普通の変数は、上記のような家1つ分で1つの家族が住んでいるのと同じ考えです。 「●県●市●番地●号」という住所を指定すると、荷物をその家に届けることが出来ます。 変数名を指定すると、値をその変数に設定することが出来ますよね。 通常の変数に対して、配列変数は上記のようなアパートまたはマンションのような建物のイメージです。
「●県●市●番地●号」だけでは建物の住所だけですので、住所+部屋番号を指定する必要があります。 この部屋番号が配列で言う要素番号を指しており、「●県●市●番地●号−●号室」となります。 変数名と要素番号を同時に指定することで、指定した配列の指定要素に値を設定することが出来ますね。 HSPでは数値型や文字列型等全ての配列において、1〜4次元の配列変数を扱うことが可能で、 1次元配列では「配列変数名.要素」または「配列変数名(要素)」、 2次元配列では「配列変数名.要素.要素」または「配列変数名(要素, 要素)」、 3次元配列では「配列変数名.要素.要素.要素」または「配列変数名(要素, 要素, 要素)」、 4次元配列では「配列変数名.要素.要素.要素.要素」または「配列変数名(要素, 要素, 要素, 要素)」 という形式で記述することが出来ます。 配列変数は複数の変数が集まったものだと言うことだけを聞くと 「管理はしにくいままじゃないか」とそんな声が聞こえてきそうですね。 配列変数名は通常の変数名と同じ様にHSP規則に則って決めるわけですが、通常の変数と異なるところは、 この「要素」は添字番号で管理されており、各要素への参照や代入は数値を使用します。
1 2 3 4 5 6 |
hairetsu.0 = 1 // 1つ目の要素に代入 hairetsu.1 = 2 // 2つ目の要素に代入 hairetsu.2 = 3 // 3つ目の要素に代入 mes hairetsu.0 // 「hairetsu.0」は「hairetsu」と書いても良い mes hairetsu.1 mes hairetsu.2 |
1 2 3 4 |
hairetsu = 1, 2, 3 // 一気に入れます mes hairetsu.0 mes hairetsu.1 mes hairetsu.2 |
1 2 3 4 5 6 7 8 |
// 値のセット repeat 3 hairetsu.cnt = cnt + 1 // 要素番号にカウンタを使用する loop // 値の表示 repeat 3 mes hairetsu.cnt loop |
1 2 3 |
// A.1.1 = 123, 456, 789 A.2.2 = 100 A.0.1 = 1, 2, 3 |
1 2 3 4 5 6 7 8 |
A.1.1.2 = 2 X = 1 buf(2+X) = 3 buf(A.1.1.2) = -2 buf(buf(2+X) + buf(A.1.1.2)) = 999 mes buf(1) mes buf(2) mes buf(3) |
1 2 |
v.0 = 0.0 // 変数vは実数型として再初期化 v.2 = 3.65 |
1 2 |
abc.0 = "" // コメントにするとエラーとなる abc.4 = "あいうえお" |
| ddim 変数名, 要素1(, 要素2, 要素3, 要素4) | |||
| 変数名 | 実数値を扱いたい変数名を指定する。 | ||
| 要素1 | 配列1次元の要素数を指定する。 | ||
| 要素2 | 2次元目も必要な場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
| 要素3 | 3次元目も必要な場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
| 要素4 | 4次元目も必要な場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
1 2 3 |
ddim float, 10 // 要素数10の実数型配列を定義する float.3 = 3.14159 mes float.3 |
1 2 |
ddim f, 5, 2 f(1, 1) = 1.234, 56.7, 8.90 |
| sdim 変数名, 文字数(, 要素1, 要素2, 要素3, 要素4) | |||
| 変数名 | 文字列を扱いたい変数名を指定する。 | ||
| 文字数 | 1要素に代入する文字数を指定する。 | ||
| 要素1 | 文字列型配列にする場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
| 要素2 | 2次元目も必要な場合は指定します。(必要なければ直前のコンマ以降は書かない) | ||
| 要素3 | 3次元目も必要な場合は指定します。(必要なければ直前のコンマ以降は書かない) | ||
| 要素4 | 4次元目も必要な場合は指定します。(必要なければ直前のコンマ以降は書かない) | ||
1 2 |
sdim string, 12, 10 string.5 = "Test" |
| dim 変数名, 要素1(, 要素2, 要素3, 要素4) | |||
| 変数名 | 整数値を扱いたい変数名を指定する。 | ||
| 要素1 | 配列1次元の要素数を指定する。 | ||
| 要素2 | 2次元目も必要な場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
| 要素3 | 3次元目も必要な場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
| 要素4 | 4次元目も必要な場合は指定する。(必要なければ直前のコンマ以降は書かない) | ||
1 2 3 4 5 |
temporary.100 = 1, 2, 3, 4, 5, 6, 7, 8, 9 // 一時的に配列サイズ108までが必要であったとする repeat 9, 100 mes temporary.cnt loop dim temporary, 3 // 使用メモリ縮小 |
| ldim 変数名, ラベル数 | |||
| 変数名 | 対象とする変数名を指定する。 | ||
| ラベル数 | 変数用に割り当てるラベル数を指定する。 | ||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
*label_0 randomize ldim lbl, 3 lbl = *label_1, *label_2, *label_3 gosub lbl(rnd(3)) mes "label_0 に戻りました" stop *label_1 mes "label_1 が実行されました" return *label_2 mes "label_2 が実行されました" return *label_3 mes "label_3 が実行されました" return |
| newlab 変数名, ラベル | |||
| 変数名 | 初期化する変数名を指定する。 | ||
| ラベル | 以下のいずれかを指定する。 ラベル名指定時は通常の変数代入と同じ効果。 「0」指定時はnewlabの次処理位置を記憶し、移動可能とする。 「1」指定時はnewlabの2つ先の処理位置を記憶し、移動可能とする。 | ||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
*label1 mes "label1" gosub *label2 gosub lbl // 変数lblに入れた*label3へジャンプ stop *label2 mes "label2" newlab lbl, *label3 // 「lbl = *label3」としたのと同じ return *label3 mes "label3" return |
1 2 3 4 5 6 7 8 9 10 |
*label1 mes "*label1" gosub *label2 gosub lbl // 「mes "*label2"」の位置へジャンプ stop *label2 newlab lbl, 0 // 「mes "*label2"」の位置を変数に入れる mes "*label2" return |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
*label1 mes "*label1" gosub *label2 gosub lbl // 「*label3」へジャンプ stop *label2 mes "*label2" newlab lbl, 1 // 「*label3」の位置を変数に入れる return *label3 mes "*label3" gosub *label2 return |
| alloc 変数名, サイズ | |||
| 変数名 | 対象とする変数名を指定する。 | ||
| サイズ | 変数用に割り当てるサイズをバイト単位で指定する。 | ||
1 2 |
alloc S, 128 S = "128バイト分確保しておきましょう。その後の使い道はご自由に、ご利用は計画的に。" |