メニュー選択って普通に組むと意外と面倒くさいんですよね。
キー入力待ち状態とカーソルの移動状態で処理を分けて、滑らかにカーソル移動させるために変数持たせて・・・とか。
こんなときこそコルーチンの出番だろうと思い、
luaのコルーチンを使って、簡易なメニュー選択画面作ってみました。
-- メニュー選択用コルーチン
c = coroutine.create(function()
function cursorY(idx)
return 20 + (idx - 1) * 16
end
menuIdx = 1
repeat
-- キー入力
repeat
inputed = false
if love.keyboard.isDown("z") then
inputed = true
for i=1,60 do
selectedMenuItem = menu[menuIdx]
coroutine.yield()
end
selectedMenuItem = ""
end
if love.keyboard.isDown("up") then
inputed = true
menuIdx = menuIdx - 1
if menuIdx < 1 then
menuIdx = #menu
end
elseif love.keyboard.isDown("down") then
inputed = true
menuIdx = menuIdx + 1
if menuIdx > #menu then
menuIdx = 1
end
end
coroutine.yield()
until inputed
-- カーソル移動
repeat
y = y + (cursorY(menuIdx) - y) * 0.2
coroutine.yield()
until math.abs(y - cursorY(menuIdx)) < 2
y = cursorY(menuIdx)
until false
end)
-- メニュー項目
menu = {"Start", "Continue", "Shutdown"}
function love.load()
y = 20
selectedMenuItem = ""
end
function love.update()
coroutine.resume(c)
end
function love.draw()
love.graphics.setColor(122,255,255, 50)
love.graphics.rectangle("fill", 20, y, 200, 16)
love.graphics.setColor(255,255,255, 255)
for idx, item in ipairs(menu) do
love.graphics.print(item, 20, 22 + (idx - 1)* 16)
end
if selectedMenuItem ~= nil and selectedMenuItem ~= "" then
love.graphics.print(selectedMenuItem, 20, 240, 0, 5, 5)
end
end
通常ならifやswitchで処理を分けるところを、直線的に書けるのが嬉しいですね。
ちなみに、画面の表示用にゲームエンジンのLÖVEを使用しています。
インストール方法は永遠無窮の開発室様で分かりやすく説明されています。