こんにちは、ロブスタのハルです!
前回の講座ではif文について3つのプログラムの演習をしました。
今回は制御構文の2つ目while文について解説します。
前回の講座を見ていない方はこちらからご覧ください。
while文について
制御構文にはある条件のときに実行する文とある条件の間繰り返す文があると言いました。
今回のwhile文はある条件の間繰り返す役割を持っています。一般的にwhileループと呼ばれることが多いです。
現実世界で例を出すと、水が沸騰するまで加熱するとか信号が赤の間止まっておく、スマホが充電されるまで待つといった動作を表します。
while文をコードで書くと次のようになります。
while 継続条件式 do
処理内容
end
※whileは日本語で~の間、doは~するといった意味を持ちます。
継続条件式にはif文と同じように演算子を使うことができます。
repeat文
while文は継続条件式によってはその中身を一度も実行しないことがあります。
一方でrepeat文を使うことで必ず一度はその中身を実行する処理を書くことができます。
repeat文をコードで書くと次のようになります。
repeat
処理内容
until 終了条件式
※repeatは日本語で繰り返す、untilは~までといった意味を持ちます。
終了条件式には演算子を使うことができます。
例題
while文
local count = 1
while count <= 10 do
print(count)
count = count + 1
end
上の例は1~10までの数字を出力するプログラムです。
初期値として1行目でcountに1を代入しています。
3行目から6行目はwhile文となっています。
まず、count <= 10を満たしているかどうかを調べます。ここではcount = 1で10以下なのでtrueとなり、4・5行目が実行されます。4行目ではcountの中身(1)を出力し、5行目ではcountに1を足しています。while文は継続条件式がtrueの間はその中身を繰り返すので再び3行目に戻ります。今回はcount = 2で10以下なのでtrueとなり、4・5行目が繰り返されます。こうして10回while文の中身が繰り返された後、count = 11のときには10以下ではないのでfalseとなり、while文の中身を実行せずに終了します。
もし、while文の最後の行でcountを+1しなければ永遠にcount <= 10がtrueとなってしまうので終わることなく数字が出力されてしまいます。このように終わりがなくずっと処理が走ることを無限ループと呼びます。無限ループは動作が重くなったり、最悪の場合ゲームがフリーズ・クラッシュしたり、データが破損してしまうこともあるので注意しましょう。
一方で無限ループをわざと実装する場合もあります。この場合は中にif文を書いて条件を満たした場合に終了するような処理をさせることが多いです。
また、今回のcountのように回数を数えるための変数をカウント変数と呼ぶことがあります。
repeat文
local count = 1
repeat
print(count)
count = count + 1
until count >= 10
上の例は先程と同じく1~10までを出力するプログラムです。
初期値としてcountに1を入れているところは同じです。repeat文はwhile文と違って最初にrepeat文の中身が実行されます。その後count >= 10を満たしているかどうかを判定します。
while文ではcountが10以下の間繰り返すという条件でしたがrepeat文ではcountが10以上になったら終了するという条件になっていることに注意してください。
演習
概要
今回は演習としてパーツを1秒ごとに1スタッドずつ動かすプログラムを書いてみたいと思います。
これは1秒ごとに動かすという同じ処理の繰り返しなのでwhile文が使えそうだということがわかりますね。
実装
パーツの作成
まずはいつも通りRoblox studioを開いてワークスペース上に好きなパーツを作っていきます。
パーツの名前はそのままPartとしています。
プログラムを書く
流れを考える
今回はPartオブジェクトに新しいスクリプトを追加しましょう。
さて、今回のプログラムはほぼ例題通りで作れます。
そこまで難しいものではないので少しだけ自分で考えてみてくださいね。
…
…
…
考えてみましたか?
僕は次のような流れで作ろうと思います。
- Partオブジェクトを変数に代入しておく
- 移動距離、移動上限、待ち時間、カウント変数を決める
- カウント変数が決めた移動上限になるまでpartの座標を変える
- 同時にカウント変数に+1し、1秒待つ
- もし終了したらprint文でfinished!と表示する
コーディング
local part = script.Parent
local moveDistance = 1
local moveLimit = 10
local waitTime = 1
local moveCount = 0
while moveCount < moveLimit do
part.Position = part.Position + Vector3.new(moveDistance, 0, 0)
moveCount = moveCount + 1
task.wait(waitTime)
end
print("finish!")
今回はこのように実装しました。
まず、1行目ではこのスクリプトの親であるPartオブジェクトを変数partに代入しています。
続いて3~6行目では移動距離moveDistance, 移動上限moveLimit, 待ち時間waitTime, カウント変数moveCountをそれぞれ定義しています。
8~12行目でwhile文を定義しています。9行目ではpartのPositionをmoveDistance分だけ増加させています。10行目ではカウント変数に1を足しており、11行目ではwaitTime分だけ時間を待っています。なお、継続条件式としてmoveCount < moveLimitという式を書いています。これはカウント変数が移動上限よりも小さい間はwhile文を実行するという意味です。
おそらく9行目でなんでVector3を使っているの?と思ったことでしょう。その理由はpartのPositionプロパティがVector3型だからです。公式リファレンスのこちらのページでBasePartから継承したプロパティの欄にPositon: Vector3と書いてありますね。これはPositonプロパティの型がVector3ですよということを表しています。
テスト
コードが書けたら実行してみてください。パーツが1スタッドずつ動いて10回繰り返された後に止まるのが確認できたと思います。
Vector3型
Vector3型は3D空間の座標ベクトルを表すデータ型です。
…ちょっと難しいですよね。簡単に言うとゲーム上の位置を表すものです。
Vector3型はコンストラクタを使うことでその座標の位置を作成します。
Vector3.new(2, 5, 7)
例えば上のように書くとx=2, y=5, z=7という位置を返してくれます。
また、Vector3型同士は計算することができます。
Vector3.new(1, 2, 3) + Vector3.new(4, 5, 6)
上のような計算をすると、その結果はVector3.new(5, 7, 9)となります(x同士、y同士、z同士を足したもの)。
part.Position = part.Position + Vector3.new(moveDistance, 0, 0)
つまり、今回のコードのこの部分はもとのpartのPosition(Vector3.new(x, y, z))に対して、Vector3.new(moveDistance, 0, 0)だけ足すことになるのでx座標だけmoveDistance分増やしていることになります。
まとめ
- while文は繰り返し処理を実行する
- repeat文は必ず1回実行する繰り返し処理を実行する
- while文またはrepeat文にはカウント変数を使う
- Vector3型は3D空間の座標ベクトルを表す
お疲れ様でした。今回は制御構文の一つであるwhile文について解説しました。繰り返し処理ができるようになるとコードをかなり短縮することができますね。
次回はもう一つの繰り返し処理であるfor文について解説したいと思います。
コメント