繰り返し処理にはテーブルを使うと便利である。
参考:https://symfoware.blog.fc2.com/blog-entry-450.html
目次
for doの基本形
for i = 1 , 5 , 1 do
print(i) — 1 2 3 4 5が出力される Lua
imgui.TextUnformatted(i) — 1 2 3 4 5が出力される FlyWithLua
end
0から始めることも出来る。出力は6つになるが、5の設定であることに注意!
for i = 0, 5, 1 do
imgui.TextUnformatted(i) — 0 1 2 3 4 5が出力される FlyWithLua
end
ボタンの繰り返し
imgui.SameLine()で横に並べる。これが無いと下に並ぶことになる。
------------------------------------------------------------------------ -- ウインドウの作成 wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") --wnd変数をセット float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする ------------------------------------------------------------------------ --ボタンを作成するための関数 function im_on_build(wnd, x, y) text = {"ABC","BVC","GFD"} for i = 1, #text do if imgui.Button(text[i]) then end imgui.SameLine() end end
テキストの繰り返し
wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") --wnd変数をセット float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする ------------------------------------------------------------------------ local button_number = {"1","2","3","4","5"} --ボタンを作成するための関数 function im_on_build(wnd, x, y) for i = 1, #button_number do imgui.TextUnformatted(button_number [i]) imgui.SameLine() end end
数字だけなら、こっちが簡単。上と同じ結果になる。
wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") --wnd変数をセット float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする ------------------------------------------------------------------------ --ボタンを作成するための関数 function im_on_build(wnd, x, y) for i = 1, 5 do imgui.TextUnformatted(i) imgui.SameLine() end end
数字の途中から始める
5からスタートする場合
5からスタートする場合、for i = 5 , 10 , 1 do
for i = 5 , 10 , 1 do
print(i) — 1 2 3 4 5が出力される Lua
imgui.TextUnformatted(i) — 1 2 3 4 5が出力される FlyWithLua
end
テキストの位置を設定する
基本的には左上から下に並べられる。位置を指定したい場合は以下のようになる。9行と10行に入っている。
imgui.SetCursorPosX(40)
imgui.SetCursorPosY(60)
wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") --wnd変数をセット float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする ------------------------------------------------------------------------ local button_number = { "1", "2", "3", "4", "5" } --ボタンを作成するための関数 function im_on_build(wnd, x, y) text = { "ABC", "BVC", "GFD" } imgui.SetCursorPosX(40) imgui.SetCursorPosY(60) for i = 1, #button_number do imgui.TextUnformatted(button_number[i]) imgui.SameLine() end end
テキスト間の横送りを指定する
6行目にテーブルを作成して、その変数を11行目に入れている。button_numberは上のように不要にすることもできる。
wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") --wnd変数をセット float_wnd_set_imgui_builder(wnd, "im_on_build") --関数を読み込みセットする ------------------------------------------------------------------------ local button_number = { "1", "2", "3", "4", "5" } text_Distance = {"30", "70", "110", "150", "190"} --ボタンを作成するための関数 function im_on_build(wnd, x, y) imgui.SetCursorPosY(60) for i = 1, #button_number do imgui.SetCursorPosX(text_Distance[i]) imgui.TextUnformatted(button_number[i]) imgui.SameLine() end end
特定の部分だけを表示しないようにする
for文のある部分だけを削除(表示しない)するようにする方法。下の分は3番目を対象にしている。このように3つ目が非表示になる。
for i = 1, 5, 1 do
if i == 3 then
goto continue
end
–内容を記述
::continue::
end
---------------------------------------------------- wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) for i = 1, 5, 1 do if i == 3 then goto continue end imgui.TextUnformatted(i) --内容を記述 ::continue:: end end
1つおきに表示する場合(1 3 5と1つ飛びで出力される)
for i = 1 , 5 , 2 do
print(i) — 1 3 5が出力される
imgui.TextUnformatted(i)–FlyWithLuaの場合
end
後ろから表示する場合(3、2、1の順番で表示される)
for i = 3 , 1 , -1 do
print(i) — 3 2 1と逆に出力される
imgui.TextUnformatted(i)–FlyWithLuaの場合
end
(break)でループ処理を途中で終了する
数字のカウントを途中で止める。以下は2で止めるので1しか表示されない。
for i = 1 , 3 do
if i == 2 then
break
end
print(i) — 1が出力される end
imgui.TextUnformatted(i)–FlyWithLuaの場合
while文
以下はFlyWithLuaで検証していないことに注意!
条件式がtrueの間、ループを実行します。
while [評価式] do
end
サンプルとして、1から5までループし、数を表示してみます。
> v = 1
> while v <= 5 do
>> print(v)
>> v = v + 1
>> end
1
2
3
4
5
repeat
ループの中身を必ず一回は実行し、最後にループを脱出するかの評価を行いたい場合は、repeatを使用します。
repeat
until [評価式]
評価式がtureになったらループを脱出します。
> v = 1
> repeat
>> print(v)
>> v = v + 1
>> until v == 6
1
2
3
4
5
for
forの構文はこんな感じ。
for [変数名] = [開始値],[終了値] do
end
ループ時、加算する値を指定できます。
for [変数名] = [開始値],[終了値],[加算値] do
end
サンプルは以下の通り。
> for i = 1, 5 do
>> print(i)
>> end
1
2
3
4
5
偶数のみ表示。
> for i = 2,10,2 do
>> print(i)
>> end
2
4
6
8
10
イテレーター(配列のようなデータ構造の要素を順に処理する構文)
「in ipairs」でも「in pairs」でも動作する。
Lua では、for ループで特定のテーブルを反復処理する場合に、pairs() と ipairs() 関数の両方を使用できる。 これらの関数は両方とも、キーが要素のインデックスであり、値がそのインデックス テーブルに格納されている要素であるキーと値のペアを返します。
Pairs() 関数と ipairs() 関数の最初の違いは、ipairs() 関数は確実にキーの順序を維持するのに対し、pairs() 関数はキーの順序を維持しないこと。
ipairs()はインデックスと値のペアを返し、主に数値テーブルに使用されます。配列内の非数値キーは無視されますが、インデックスの順序は確定的です(数値順)。
---------------------------------------------------- wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) coffee = { "Blue mountain", "Guatemala", "Hawaii Kona" } for idx, val in ipairs(coffee) do imgui.TextUnformatted("coffee[" .. idx .. "] = " .. val) end end
連想配列のキーと値のペアを返し、全ての要素にアクセスできる。
---------------------------------------------------- wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) coffee2 = { bluemountain_coffee = "ABC", guatemala_coffee = "JHG", hawaii_coffee = "GGH" } for key, val in pairs(coffee2) do imgui.TextUnformatted(key .. " = " .. val) end end
テーブルを使った繰り返し
tableの中身を表示するには、以下の構文を使用します。
for [key変数], [value変数] in pairs([table “” not found /]
) do
end
tableをリストとして使用している場には、keyにはインデックスが入ります。2つの内容を同時に処理。
tableをリストとして使用している場合のサンプル。
t = {“a”, “b”, “c”, “d”, “e”}
for key, value in pairs(t) do
imgui.TextUnformatted(key .. ” ” .. value)
end
実際のスクリプト例
wnd = float_wnd_create(200, 150, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") function im_on_build(wnd, x, y) t = { "a", "b", "c", "d", "e" } for key, value in pairs(t) do imgui.TextUnformatted(key .. " " .. value) end end
tableを連想配列として使用している場合のサンプル。
u = {}
u[1] = “a”
u[3] = “b”
u[2] = “c”
u[4] = “d”
u[“hello”] = “world”
for key, value in ipairs(u) do
imgui.TextUnformatted(key .. ” ” .. value)
end
「ipairs」と「pairs」では使い方が少し違ってくる。
「ipairs」にすると、このスクリプトに関しては「hello = world」が表示されなくなる。
ipairs()はインデックスと値のペアを返し、主に数値テーブルに使用されます。配列内の非数値キーは無視されますが、インデックスの順序は確定的(数値順)。
下を見るとわかるように、1から数値順に表示されていて、スクリプトに記述されている順番は無視されている。
wnd = float_wnd_create(200, 150, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") function im_on_build(wnd, x, y) u = {} u[1] = "a" u[3] = "b" u[2] = "c" u[4] = "d" u["hello"] = "world" for key, value in ipairs(u) do imgui.TextUnformatted(key .. " " .. value) end end
13行めの「ipairs(u)」を「pairs(u)」に変更するとうまく表示される。
pairs()はキーと値のペアを返し、主に連想テーブルに使用されます。キーの順序は指定されていません。(順番が確定的でない?)
順番は同じように数値の番号の順番で表示されペアの文字が返されている、違うのはテキストが表示されるということになる。
以下のような書き方もある。
しかしこれは「pairs(t)」を「ipairs(t)」とすると表示されなくなるので使えなるので注意。
t = {}
t.a = “a_value”
t.b = “b_value”
t.c = “c_value”
t.d = “d_value”
t.e = “e_value”
for key, value in pairs(t) do
imgui.TextUnformatted(key .. ” ” .. value)
end
break
ループを途中で脱出する場合には、breakが使用できます。
> v = 0
> while true do
>> if v == 5 then
>> print(“break実行”)
>> break
>> end
>> print(v)
>> v = v + 1
>> end
0
1
2
3
4
break実行
forの中にforを入れる
縦横を繰り返し。この方法だと最初の行を繰り替えしているだけ。
---------------------------------------------------- wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) for i = 1, 5 do for j = 1, 10 do imgui.TextUnformatted(j) imgui.SameLine() end imgui.TextUnformatted("\n") end end
for文で作成した数値を特定の位置で改行する
この方法だと好きな位置で改行を設定することができる。必要な改行位置分だけelseifを作成する必要があるのが面倒だが、それ以外に方法が見つからない。
andとかorは最初の条件になれば、そこで終了してしまうので1つだけになってしまう。
---------------------------------------------------- wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) for i = 1, 10 do imgui.TextUnformatted(i) imgui.SameLine() if i == 3 then imgui.TextUnformatted("\n") elseif i == 5 then imgui.TextUnformatted("\n") end end end
ボタンを繰り返して10ボタン目で改行する
---------------------------------------------------- wnd = float_wnd_create(600, 150, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) for i = 1, 30 do if imgui.Button("Edit", 50, 40) then end imgui.SameLine() if i == 10 then imgui.TextUnformatted("\n")--本来テキストが入るところに改行を入れるとボタンを改行できるようになる。 elseif i == 20 then imgui.TextUnformatted("\n")--あとはelseifで同じ改行が繰り返されるのでこれ1つで良い。 end end end
while文
---------------------------------------------------- wnd = float_wnd_create(400, 200, 1, true) float_wnd_set_title(wnd, "Buttons") float_wnd_set_imgui_builder(wnd, "im_on_build") ---------------------------------------------------- function im_on_build(wnd, x, y) local cnt = 1 while cnt <= 5 do imgui.TextUnformatted("cnt = " .. cnt) cnt = cnt + 1 end end
Luaでは
local cnt = 1 while cnt <= 5 do print("cnt = "..cnt) cnt = cnt + 1 end
「0」又は「-5」からスタートする
Luaではインデックス1で配列を開始するのが通例です。配列も1で始まる場合は、何もしなくてもその機能を直接使用できます。
しかし、0から始めたい場合があるのです。その場合は以下のようにする方法があるとか。
これもまだ検証していない。
a = {} — new array
for i=1, 10 do
a[i] = 0
end
-5から始める
— -5 から 5 までのインデックスを持つ配列を作成します
a = {}
for i=-5, 5 do
a[i] = 0
end