airstruck wrote:Interesting approach. I'd like to see an example of that being used in a in a game, do you know of one? It's a little hard for me to tell from your example which parts are meant to be repeated for different menus and which parts are meant to be reusable. I suspect it could be simplified a lot by leveraging some kind of promise-like pattern, but maybe I'm misreading it.
To expand on it a bit, here's some incomplete snippets from my personal one-hour-a-week-for-fun project
Code: Select all
function states.action_menu:run_action_menu()
local W, H = 18, 6
local sw, sh = graphics.max_window_size()
local main_menu = systems.menubox.assembly.builder.new()
:at(math.floor((sw-W)/2), sh-H+1):size(W, H)
:option("Talk", "talk")
:option("Item", "use")
:option("Equip", "equip")
:option("Search", "search")
:option("Attack", "attack", math.floor(W/2)+1, 1)
:option("Magic", "mag")
:option("Status", "stats")
:option("System", "system")
:build()
local menu_close_then = menu_open(self.entities, main_menu)
local function loop()
if input.tap.cancel then
menu_close_then(gamestate.pop)
elseif input.tap.action then
local command = main_menu.menu_config[main_menu.menu_selection].id
if command == "talk" then
if self.callback then self.callback() end
elseif command == "stats" then
return menu_close_then(self.run_stats_window, self)
end
else
local cmd = systems.menubox.update(self.entities)
if cmd == 'advance' then
graphics.set_dirty()
end
end
return loop
end
return loop
end
function states.action_menu:run_stats_window()
local sw, sh = graphics.max_window_size()
local W, H = 20, 12
local stats_window = systems.drawboxes.assembly.new_window_builder()
:at(math.floor((sw-W)/2), math.floor((sh-H)/2)):size(W, H)
:text(("Level %7i"):format(99), 1, 1)
:text(("Experience %7i"):format(99999), 1, 2)
:text(("Next Level %7i"):format(9999), 1, 3)
:text("-", 1, 4)
:text(("Hit Points %3i/%3i"):format(999, 999), 1, 5)
:text("", 1, 6)
:text("-", 1, 7)
:text("-", 1, 8)
:text("-", 1, 9)
:text(("Carry Weight %2i/%2i"):format(99, 99), 1, 10)
:build()
local menu_close_then = menu_open(self.entities, stats_window)
local function loop()
if input.tap.cancel then
return menu_close_then(self.run_action_menu, self)
end
return loop
end
return loop
end
I haven't had the chance to pare this down to its bare minimums yet, but it works for me.