A013.メニュー処理基本

メニューの処理の基本的なプログラムです。

http://dxlib.o.oo7.jp/dxprogram.html#N7

DXライブラリを参考にしました!

 

-- conf.lua

function love.conf(t)
	t.window.width = 640
	t.window.height = 480
end

640x480で設計していますので、コンフィグファイルを設定しておきましょう。

 

-- main.lua

local	MOJI_SIZE = 24
local	CURSOR_INTERVAL = 0.2

local	menus = {}

local	font = nil
local	cursor = 1
local	cursor_dt = 0
local	keystate = {}

function love.load()
	-- ファイルからフォントを作成
	font = love.graphics.newFont("ipaexg.ttf", MOJI_SIZE)
	
	-- フォントをセット
	love.graphics.setFont(font)
	
	-- メニュー、赤い箱を描画する
	do
		local	menu = {}
		
		-- タイトル
		menu.title = "赤い箱を描画する"
		
		-- 描画処理
		menu.draw = function()
			draw_box(0, 0, 640, 480, {255, 0, 0}, true)
		end
		
		table.insert(menus, menu)
	end
	
	-- メニュー、ランダムにドットを打つ
	do
		local	menu = {}
		
		-- タイトル
		menu.title = "ランダムにドットを打つ"
		
		-- ドット群
		menu.DOT_INTERVAL = 0.2
		menu.dots = {}
		menu.dot_dt = 0
		
		-- 描画処理
		menu.draw = function()
			for i, dot in ipairs(menu.dots) do
				draw_box(dot.x, dot.y, dot.x + 3, dot.y + 3, dot.color, true)
			end
		end
		
		-- 更新処理
		menu.update = function(dt)
			if #menu.dots == 0 or menu.dot_dt >= menu.DOT_INTERVAL then
				menu.dots = {}
				for i = 1, 1000 do
					local	dot = {}
					
					dot.x = love.math.random(love.graphics.getWidth() - 3)
					dot.y = love.math.random(love.graphics.getHeight() - 3)
					dot.color = {}
					for i = 1, 3 do
						table.insert(dot.color, love.math.random(255))
					end
					table.insert(menu.dots, dot)
				end
				menu.dot_dt = 0
			end
			menu.dot_dt = menu.dot_dt + dt
		end
		
		table.insert(menus, menu)
	end
	
	-- メニュー、グラデーションを描く
	do
		local	menu = {}
		
		-- タイトル
		menu.title = "グラデーションを描く"
		
		menu.draw = function()
			for i = 0, 480 - 1 do
				draw_box(
					0,
					i,
					love.graphics.getWidth(),
					i + 1,
					{255, 255, 255 * i / love.graphics.getHeight(), 64},
					true
				)
			end
		end
		
		table.insert(menus, menu)
	end
	
end


function love.keypressed(key, irepeat)
	keystate[key] = true
	if key == "escape" then
		love.event.quit()
	end
end


function love.keyreleased(key)
	keystate[key] = false
end


function love.update(dt)
	
	-- 選択された更新処理を実行
	if type(menus[cursor].update) == "function" then
		menus[cursor].update(dt)
	end
	
	if cursor_dt >= CURSOR_INTERVAL then
		if keystate.up then
			cursor = cursor - 1
			if cursor < 1 then cursor = #menus end
			cursor_dt = 0
		end
		if keystate.down then
			cursor = cursor + 1
			if cursor > #menus then cursor = 1 end
			cursor_dt = 0
		end
	end
	cursor_dt = cursor_dt + dt
end

function draw_box(
	-- DXライブラリ風
	left,
	top,
	right,
	bottom,
	colors,
	fill_flag
	)
	-- なければ、初期セット
	colors = colors or {}
	fill_flag = fill_flag or true
	
	-- fillを生成
	local	fill = "line"
	if fill_flag then fill = "fill" end
	
	-- 色をセット
	local	get_color = { love.graphics.getColor() }
	love.graphics.setColor(colors[1] or 0, colors[2] or 0, colors[3] or 0, colors[4] or 255)
	
	-- 描画!
	love.graphics.polygon(
		fill,
		left,
		top,
		right,
		top,
		right,
		bottom,
		left,
		bottom
	)
	
	-- 色を復帰
	love.graphics.setColor(unpack(get_color))
end

function love.draw()
	
	-- 選択された描画処理を実行
	if type(menus[cursor].draw) == "function" then
		menus[cursor].draw()
	end
	
	-- タイトルを表示する
	for i = 1, #menus do
		if type(menus[i].title) == "string" then
			love.graphics.printf(menus[i].title, 32, 32 * i, love.graphics.getWidth())
		end
	end
	
	-- タイトル横に選択位置を表示する
	draw_box(8, 2 + 32 * cursor, 8 + 16, 2 + 32 * cursor + 16, {255, 255, 0}, true)
	
end

main.luaは、UTF-8で保存しておく必要があります。

方法は、012章をご覧ください。

 

カーソル上下で、項目を選択します。

選択に合わせて画面が切り替わります!

 

love.loadで、それぞれのメニューの処理を用意しておくのがミソです。

love.updateで、選択されているメニューにupdateのファンクションがあったら、渡します。

love.drawで、選択されているメニューにdrawのファンクションがあったら、渡します。

 

このような形で工夫していけば、選択された項目によって全く別の内容を表示することが可能になります。


[2016.08.18] 変更:0.10.1で動作するようにソースを修正