Luaプログラミング、ド基礎

# はじめに
この記事はDefoldでLuaを扱います。Lua単体の説明ではないので予めご了承ください。
また、表面だけを扱うので中級者以上の人にはちょっと物足りないかもしれません。

# プログラムの実行方法
今回はやり方だけ説明します。何も考えないで真似してください。
まず前回Empty Projectを作ったと思うので、それをダブルクリックで開いてください。
![2021-04-04_19h41_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/8bdb05ff-f9a6-e22f-ba60-599126a75e19.png)
そしたらAssetsのmainを開いて、**main.collection**を開いてください。
![2021-04-04_19h43_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/837ae622-d6bf-568b-a5db-0afe6fb45422.png)
次に、右側のOutlineのCollectionを右クリックして、**「Add Game Object」**を押します。
![2021-04-04_19h43_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/d535cc6d-0f33-385f-b6f7-baa8cb17e90c.png)
出来たゲームオブジェクトを右クリックして、**「Add Component File」**を押します。
![2021-04-04_19h48_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/397d256c-9a3e-f826-c492-c7cab547222c.png)
出てきた画面で**〇〇.script**を選択します。これは[この記事](https://qiita.com/nonzu/items/4c3a01c389c7e8a17f5b)の時に作ったファイルです。(僕の画面では Script.script です。)
![2021-04-04_19h48_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/0f424c4b-5519-9213-17cf-6cb6a6325b48.png)

一旦、ここまでで何をやったのか説明します。
前回紹介した**"世界(Collection)"**に**"物体(Game Object)"**を追加して、その物体に対して**"プログラム(Script)"**を設定しました。
こういう風に設定すると、**物体**は**プログラム**の通りに動いてくれます。そしたらAssets内の**〇〇.script**を選択して、編集画面を開いてください。(僕の画面ではAtomを使用しています。)

スクリプトを開くと**init, final, update, on_message, on_input, on_reload**があると思います。それぞれに意味がありますが、今回は**init**のみを使用します。
これからのコードは **function init(self)** から次の **end** の間に記述してください。(下の赤枠内に記述します。)
![2021-04-04_19h57_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/cd7a3ed8-123a-317e-8863-dcda9b7291f6.png)
initの中に書いたプログラムはゲームオブジェクトが作られたときに実行されます。
実行はDefoldの画面で **F5**を押すと行うことができます。最初は真っ暗な画面が出ると思います。


# コメント
1つ目は、コメントです。コメントは書いてもプログラムに何の影響も与えません。
コメントは以下のように記述します。

```lua
function init(self)
  -- 1行のコメント

  --[[1行目
  2行目
  3行目
  複数行のコメントはこんな感じで記述します。]]
end
```
わかりましたかね？Atomなどで入力すると灰色になると思います。灰色になっているコードは実行されません。
簡単に言うと**読み飛ばされる部分**です。複数行コメントを終わらせるには **]]**を記述する必要があります。
例えば、「ここは〇〇の処理」とか「〇〇は〇〇の変数」とか書くとコードがわかりやすくなります。

# print
2つ目はprintです。これはめっちゃ使います。変数の中身をチェックしたり、計算結果をチェックしたり、変数の型をチェックしたりいろいろなことに使います。
例えば、

```lua
function init(self)
  print(1)
end
```
と入力して、実行してみると
![2021-04-04_20h11_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/f9ae1624-f448-2b9c-9f71-31e4dba39fcd.png)
こうなります。何も写ってない青枠で囲ったウィンドウがゲームの画面です。
したの**Console**を見てみると、`DEBUG:SCRIPT: 1` と書いてあると思います。これの「:」から後が出力です。
試しに、

```lua
function init(self)
  print(1+2)
end
```
と入力してみると 3 と出力されます。

ちなみに、functionの行とendの行以外にTab(空白)が入っているのは**インデント**と言ってコードを見やすくするために使います。
他の命令でもインデントすることはありますが、とりあえず「functionの中身はインデントすると見やすいな」と思っていてください。
ここから先はfunctionの行とendの行を省略するので適宜インデントを入れてコードを実行してみてください。

# 四則演算(＋ － × ÷ …)
こっから計算です。まず、足し算、引き算、掛け算、割り算の基本的な計算を四則演算といいます。
それのやり方です。一覧にするとこんなかんじです。

|記号|プログラム|
|:--:|:--:|
|＋|+|
|－|-|
|×|*|
|÷|/|
|…(余り)|%|

まぁやってみればわかると思います。

```lua
print(3+5)  --結果: 8
print(8-6)  --結果: 2
print(7*3)  --結果: 21
print(8/3)  --結果: 2.6666666666667
print(8%3)  --結果: 2
```
まぁただの計算をやってくれます。

# 条件分岐(if)
ここからは、条件分岐です。if文とか言います。超重要です。こんな風に書きます。

```lua
if --[[<条件式>]] then
  -- if文もインデントをいれたほうがいいです。
end
```
条件式の部分には、基本的に **true**(真)か **false**(偽) を入れます。if文の中身はは条件式がtrueのときに実行されます。
たとえば

```lua
if true then
  -- 絶対に実行される。
end

if false then
  -- 絶対に実行されない。
end
```
こんなかんじです。printしてみたらわかると思いますが
`3==3`はtrue `3==5`はfalseでとなることがわかると思います。

```lua
print(3 == 3)               --結果: true
if 3 == 3 then              --結果: if と then の間がtrueだから中身が実行される
  print("3は3だよ！")      --結果: 実行されて出力される。(文章を書くときは " [Shift+2] で囲むこと)
end                       -- if文終わり

print(3 ==5 )                --結果: false
if 3 == 5 then               --結果: if と then の間がfalseだから中身は実行されない
  print("3は5じゃねーよ！")  --結果: プログラムを書いたけど実行されない。
end                        -- if文終わり
```
コードの全てにコメントを付けたので上から順に追っていけばわかると思います。
ちなみに **==** は比較するときに使います。 3=3 にするとエラーとなるのでお気をつけください。(**「=」**単体は別の意味がある。)

もっと複雑な条件分岐で**and**や**or**、**not**を使うものもあります。
A 〇〇 Bという風に記述します。
A and B は両方trueのときにtrue、それ以外はfalseとなります。
A or B はどっちかがtrueのときにtrueになります。
not A はAの真偽を逆にします。
例えばこんなかんじです。

|条件式|要するに|結果|
|:-:|:-:|:-:|
|3==3 and 5==5|true and true|true|
|3==3 and 5==8|true and false|false|
|3==5 or 5==8|true or false|true|
|3==5 or 5==8|false and false|false|
|not 3==5|not false|true|
|(not 3==5) and (5==5 or 5==8)|(not false) and (true or false)|true|
具体例を見ればイメージできると思います。

# 変数
ここでみんな大好き変数を紹介します。変数の中身を見るときにもprintで見ることができます。
変数って結構いろんな人が、**「箱」**と例えることが多いのですが、僕は**メタモン**だと思っています。
どんな形にでもなれるやつです。こういう風に記述します。

```lua
  var = 5
```
varっていうのは変数名で好きなように変えてOKです。変数名は分かりやすいほうが良いです。年齢なら**age**、名前なら**name**、プレイヤーの体力なら**player_hp**など何を表しているかわかりやすくしてください。
変数名には**アルファベット**、**_**、**数字**しか使えず、変数名の**1文字目に数字を使うことは出来ません**。

また、ここは**「=」**単体です。これは代入演算子と言います。
` var ← 5`っていうイメージです。数学で言う「＝」とは意味が違うので間違えないようにしてください。

変数には型があります。ここでは一部を紹介します。

|型|内容|代入の例|
|:-:|:-:|:-:|
|number|数字|i = 5|
|string|文字列|i = "代入したい文字列"|
|boolean|数字|i = true|

最初はよくわからないものだと思いますが、使ってると慣れてきます。

```lua
-- ここから変数代入
num1 = 3          -- num1に3を代入
num2 = 2          -- num2に2を代入
num3 = 5          -- num3に5を代入
str1 = "first"    -- str1に"first"を代入
str2 = "last"     -- str2に"last"を代入
boo = true        -- booにtrueを代入
 
-- ここから出力
print(num1 + num3)          --結果: 8          3 + 5 の結果
print(num1 == num2)         --結果: false      3 == 2の結果
print(num1+num2 == num3)    --結果: true       3+2 == 5の結果
print(num2 == num3)         --結果: false      3 == 5の結果
print(str1..str2)           --結果: firstlast  "first"と"last"を「..」(連結演算子)で連結 文字列の足し算はコレを使う
print(not boo)              --結果: false      not true の結果
print(defold)               --結果: nil        定義されていない変数はnilと表示されます。
```
==  や + の前後に半角スペースを入れたりするのは、見やすくするためにやってます。自分の感覚で見やすいようにスペースを空けたり空けなかったりしてください。
例えば、変数はメタモンなので、パソコンがnum1という変数を観察したときには3という数字に見えています。

# 繰り返し(for)
繰り返しは、そのまま繰り返しです。for文といいます。

```lua
for A=B,C,D do -- Aは変数名  B C Dは数字
  print(A) -- 変数名Aの中身の値を出力
end
```
こんな感じに書きます。Bは初期値、Cは最終値、Dは追加する値です。
わかりにくいと思うので具体例で紹介します。

```lua
-- 繰り返し①
for i=1,10 do -- 最初 iは1 で、iが10 より大きくなるまで繰り返す。 1回繰り返すと i は +1 される。
  print(i) -- i の値を出力 (for文でもインデントを使ったほうが見やすいです。)
end

--繰り返し②
for j=1,10,2 do -- 最初 jは1 で、jが10 より大きくなるまで繰り返す。 1回繰り返すと j は +2 される。
  print(j) -- j の値を出力 (for文でもインデントを使ったほうが見やすいです。)
end
```
繰り返し①では 1～10 が出力されたと思います。 Dの値を省略すると自動的に1に設定されます。
繰り返し②では 1, 3, 5, 7, 9 が出力されたと思います。1 から +2 ずつされて 11 になったときに 10 を超えたため繰り返しが終了しました。

# 繰り返し(while)
繰り返しにはもう1種類のwhile文というものがあります。

```lua
while bool do
  -- プログラム
end
```
bool は条件式で trueもしくはfalseです。 if文みたいですね。
while文は実際のコードで理解してみましょう

```lua
-- 例①
print("例①")
i = 1 -- i の定義
while i <= 10 do -- i が 10以下の間だけ繰り返す
  print(i) -- i を出力
  i = i + 1 -- i を 1 増やす。 数学的にはおかしいけど、i ← i + 1 と考えると分かりやすい。 i+1 を i に代入している。
end -- while文終わり

--例②
print("例②")
i = 10 -- i の定義
while i >= 0 do -- i が の0以上間だけ繰り返す
  print(i) -- i を出力
  i = i - 1 -- i を 1 減らす i ← i - 1
end -- while文終わり

-- 例③ (例①の別解)
print("例③")
i = 1 -- i の定義
while true do -- 常に繰り返す
  print(i) -- i を出力
  i = i + 1 -- i を 1 増やす
  if i > 10 then -- i が 10 より大きくなったとき
    break -- while 脱出
  end -- if文終わり
end -- while文終わり

--例④
print("例④")
i = 0 -- i の定義
while true do -- 常に繰り返す
  i = i + 1 -- i を 1 増やす
  if i == 5 then -- i が 5 のとき
    -- 実行されるけど、なにもしない　=> 5のときはなにも表示されない
  elseif i > 10 then -- -- 上のif文がすべて満たされず、 i が 10 より大きくなったとき
    break -- while 脱出
  else -- 上のif文がすべて満たされなかった時 else が実行される
    print(i) -- i を出力
  end -- if文終わり
end -- while文終わり
```
今回は何をやっているか分かりやすいようにコメントを全部付けましたが、実際にプログラムを書くときはポイントポイントでかけば十分です。
例①では 1～10 まで、②では 10～0 まで、③では 1～10 まで、④では 1～10(5を除く)という結果になったと思います。
上から順番にたどっていけば特別難しいことはやっていないので、わからなくなったらコメントを見るくらいの感じで見てもらえればなと思います。

# テーブル
最後はテーブルです。他のプログラミング言語では配列と呼ばれることもあったりします。
他の言語の配列は 0 から始まりますが、luaでは 1 から始まるのでご注意ください。
テーブルは簡単に言うと 複数の物(変数で表せるもの) を1つにまとめたものです。

```lua
table1 = {2, 3, 5, 7}
print(table1)    -- 結果: table: 0x〇〇〇〇〇〇〇〇〇〇 tableということがわかる
pprint(table1)   -- 結果: 下① tableの中身が表示される。
print(#table1)   -- 結果: テーブルの中身の数
print(table1[2]) -- 結果: テーブルの2つ目の要素をとってくる
```

```lua:実行結果①
{ --[[〇〇〇〇〇〇〇〇〇〇]]  
  1 = 2,
  2 = 3,
  3 = 5,
  4 = 7
}
```
〇〇の中身はそれぞれの環境によって異なると思いますが、僕は使ったことがないので当分は気にしなくて大丈夫です。
左の数字は何番目の要素なのかを表しています。
ここまで来たらあとは変数と同じです。

```lua
table1 = {2, 3, 5, 7}
print(table1[2] + table1[4])             -- 結果: 10    3 +7  の結果
print(table1[1]+table1[2] == table1[3])  -- 結果: true  2+3 == 5 の結果

-- 複数のテーブルを1つのテーブルにまとめることもできる
table2 = {{"のび", "のびた"}, {"みなもと", "しずか"}, {"ごうだ", "たけし"}, {"ほねかわ", "すねお"}}
pprint(table2[1])                     -- 結果: 下② 1つ目のテーブルの中身が表示される
print(table2[3][2])                   -- 結果: たけし  3つ目のテーブルの2つ目の要素が出力される
print(table2[1][1]..table2[2][2])     -- 結果: のびしずか   "のび".."しずか" の結果
```

```lua:実行結果②
{ --[[〇〇〇〇〇〇〇〇〇〇]]
  1 = "のび",
  2 = "のびた"
}
```

また、要素を○番目の表し方以外で表すこともできます。上記のコードを以下のように書いても同じことを示しています。

```lua
table2 = {nobita = {family = "のび", first = "のびた"}, sizuka = {family = "みなもと", first = "しずか"},
          gian = {family = "ごうだ", first = "たけし"}, suneo = {family = "ほねかわ", first = "すねお"}}
pprint(table2["nobita"])                                         -- 結果: 上②
print(table2["gian"]["first"])                                   -- 結果: たけし
print(table2["nobita"]["family"]..table2["sizuka"]["first"])     -- 結果: のびしずか
```

# さいごに
今回は、Luaの基本的なことを紹介してみました。
説明が難しくてなんて言ったらいいのかわからないことが多かったですが、具体例をたくさん入れたのでうまく理解してくれると嬉しいです。

忙しくて、更新頻度が低くなってしまいますが、適宜更新していこうと思います。
次回はDefoldのvmathについて説明します。

[目次](https://qiita.com/nonzu/items/73a39368855f3e1e0f28)をストックしておくと通知が飛ぶみたいなのでぜひ使ってみてください。