Ponymenu - setting default value.

Hi guys,

I’m currently making use of the ponymenu module (can be found here as part of the ponyblitz framework) and I’m struggling to modify it slightly.

Setting a menu up initially is really easy…f.e.

menu = ponymenu.new( onMenu, { align = "center", font = native.systemFont, fontSize = 32 }) menu:add("Play") menu:add("Level: 1,Level: 2,Level: 3,Level: 4,Level: 5") menu:add("Sound Off,Sound On") menu:add("Music Off,Music On") menu:add("Quit")

However, each menu item defaults to the first option.  What I’m really struggling to figure out is how to set a different value so that (taking the example above) you could set the level to the last one that was played.

In the game I’m working on the players have the option of how many levels to play, how many lives each player has etc.  These values are in a table which is saved out when changed so that they are persistent and will be defaulted to each time.

I hope this makes some kind of sense to people.

Hey @Appletreeman,

There wasn’t any way to directly control a toggle in what I build, but I do think it’s a good idea. What needs to happen is a new function that loops through all the items that have toggle and forces a toggle to a specific value. I’m going to call this function menu:set()…

 function instance:set(toggle) for i = 1, #self.items do -- loop through all items local selectedItem = self.items[i] if #selectedItem.toggles \> 1 then -- does an item have toggles for j = 1, #selectedItem.toggles do -- loop through all toggles if selectedItem.toggles[j]:lower():gsub(" ","") == toggle then -- are we the one we want? selectedItem.text = selectedItem.toggles[j] -- select it and update selectedItem.object.text = selectedItem.text selectedItem.selected = i selectedItem.name = selectedItem.text:lower():gsub(" ","") return true -- worked so stop end end end end print("WARNING: Toggle not found",toggle) end

I added some comments so you can follow along, but basically its a nested loop looking for a toggle. That lower() and gsub() are just making the item name lowercase and removing spaces, so the toggle changes from “Music On” to a more Corona-like “musicon”.

To use it, we just call it with a toggle. I added this example to ponyBlitz on GitHub

 -- keys to toggle volume and music local function key(event) local phase = event.phase local name = event.keyName if phase == "up" then elseif name == "v" then snd:toggleVolume() if snd.volume \> 0 then menu:set("soundoff") else menu:set("soundon") end end end Runtime:addEventListener( "key", key ) 

Here we are toggling the volume with the “V” key and setting the appropriate toggle to display.

https://github.com/ponywolf/ponyblitz 

Also, you may not know this, but ponymenu supports key presses and joystick control if you use it withing the framework. It’s also been battle tested in one our favorite free games that we’ve made called FlatEarths!

https://ponywolf.itch.io/flatearths

The ponyBlitz framework (plus the pixelWorld module, Tiled and Spine) is the main stuff behind this game. Check it out if you want to see what you can do in 72 hours with the right tools!

@ponywolf - Absolutely perfect.  Thank you so much.

@ponywolf

Unfortunately I’ve run into a weird problem…

If you take the following menu.lua (modified from your example project - with my mods typed in, not pasted), the option for the number of rounds works perfectly, but when the lives option is selected - regardless of it’s initial value it will always jump to ‘3’ before working normally.

-- Requirements local composer = require "composer" local snap = require "com.ponywolf.snap" local ponymenu = require "com.ponywolf.ponymenu" local snd = require "com.ponywolf.ponysound" local fx = require "com.ponywolf.ponyfx" -- Variables local to scene local scene = composer.newScene() local menu local selectedOptions = { lives = 6, -- Lives per player per frame. framesToPlay = 1 -- Total number of frames to play. } function scene:create( event ) local view = self.view -- add display objects to this group -- menu listener local function onMenu(event) local phase, name = event.phase, event.name or "none" print (phase, name) if phase == "selected" then snd:play("blip") if name == "play" then fx.fadeOut(function() composer.gotoScene("scene.game") end) elseif string.sub ( name, 1, 6 ) == "rounds" then local this = string.sub( name, 8 ) selectedOptions.framesToPlay = tonumber(this) elseif string.sub ( name, 1, 5 ) == "lives" then local this = string.sub( name, 7 ) selectedOptions.lives = tonumber(this) elseif name == "quit" then native.requestExit() end end end -- create a start menu menu = ponymenu.new( onMenu, { align = "center", font = "RobotoMono.ttf", fontSize = 32 }) menu:add("Play") local tmp = "lives:"..tostring(selectedOptions.lives) menu:add("Lives: 1,Lives: 2,Lives: 3,Lives: 4,Lives: 5,Lives: 6,Lives: 7") menu:set(tmp) local tmp = "rounds:"..tostring(selectedOptions.framesToPlay) menu:add("Rounds: 1,Rounds: 3,Rounds: 5,Rounds: 7,Rounds: 9") menu:set(tmp) menu:add("Quit") view:insert(menu) snap(menu) -- keys to toggle volume and music local function key(event) local phase = event.phase local name = event.keyName if phase == "up" then elseif name == "v" then snd:toggleVolume() if snd.volume \> 0 then menu:set("soundoff") else menu:set("soundon") end end end Runtime:addEventListener( "key", key ) end local function enterFrame(event) local elapsed = event.time end function scene:show( event ) local phase = event.phase if ( phase == "will" ) then Runtime:addEventListener("enterFrame", enterFrame) elseif ( phase == "did" ) then end end function scene:hide( event ) local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then Runtime:removeEventListener("enterFrame", enterFrame) end end function scene:destroy( event ) end scene:addEventListener("create") scene:addEventListener("show") scene:addEventListener("hide") scene:addEventListener("destroy") return scene

I’ve been through it with a fine tooth comb but cannot for the life of me figure out why it is doing it  :frowning:

Hmmm… I’m stumped.

Did you try to set it manually?  Like menu:set(“level:1”)

Maybe remove the colon?

You can always add a print() into the ponymenu lib and see what it’s trying to set?

Hey @Appletreeman,

There wasn’t any way to directly control a toggle in what I build, but I do think it’s a good idea. What needs to happen is a new function that loops through all the items that have toggle and forces a toggle to a specific value. I’m going to call this function menu:set()…

 function instance:set(toggle) for i = 1, #self.items do -- loop through all items local selectedItem = self.items[i] if #selectedItem.toggles \> 1 then -- does an item have toggles for j = 1, #selectedItem.toggles do -- loop through all toggles if selectedItem.toggles[j]:lower():gsub(" ","") == toggle then -- are we the one we want? selectedItem.text = selectedItem.toggles[j] -- select it and update selectedItem.object.text = selectedItem.text selectedItem.selected = i selectedItem.name = selectedItem.text:lower():gsub(" ","") return true -- worked so stop end end end end print("WARNING: Toggle not found",toggle) end

I added some comments so you can follow along, but basically its a nested loop looking for a toggle. That lower() and gsub() are just making the item name lowercase and removing spaces, so the toggle changes from “Music On” to a more Corona-like “musicon”.

To use it, we just call it with a toggle. I added this example to ponyBlitz on GitHub

 -- keys to toggle volume and music local function key(event) local phase = event.phase local name = event.keyName if phase == "up" then elseif name == "v" then snd:toggleVolume() if snd.volume \> 0 then menu:set("soundoff") else menu:set("soundon") end end end Runtime:addEventListener( "key", key ) 

Here we are toggling the volume with the “V” key and setting the appropriate toggle to display.

https://github.com/ponywolf/ponyblitz 

Also, you may not know this, but ponymenu supports key presses and joystick control if you use it withing the framework. It’s also been battle tested in one our favorite free games that we’ve made called FlatEarths!

https://ponywolf.itch.io/flatearths

The ponyBlitz framework (plus the pixelWorld module, Tiled and Spine) is the main stuff behind this game. Check it out if you want to see what you can do in 72 hours with the right tools!

@ponywolf - Absolutely perfect.  Thank you so much.

@ponywolf

Unfortunately I’ve run into a weird problem…

If you take the following menu.lua (modified from your example project - with my mods typed in, not pasted), the option for the number of rounds works perfectly, but when the lives option is selected - regardless of it’s initial value it will always jump to ‘3’ before working normally.

-- Requirements local composer = require "composer" local snap = require "com.ponywolf.snap" local ponymenu = require "com.ponywolf.ponymenu" local snd = require "com.ponywolf.ponysound" local fx = require "com.ponywolf.ponyfx" -- Variables local to scene local scene = composer.newScene() local menu local selectedOptions = { lives = 6, -- Lives per player per frame. framesToPlay = 1 -- Total number of frames to play. } function scene:create( event ) local view = self.view -- add display objects to this group -- menu listener local function onMenu(event) local phase, name = event.phase, event.name or "none" print (phase, name) if phase == "selected" then snd:play("blip") if name == "play" then fx.fadeOut(function() composer.gotoScene("scene.game") end) elseif string.sub ( name, 1, 6 ) == "rounds" then local this = string.sub( name, 8 ) selectedOptions.framesToPlay = tonumber(this) elseif string.sub ( name, 1, 5 ) == "lives" then local this = string.sub( name, 7 ) selectedOptions.lives = tonumber(this) elseif name == "quit" then native.requestExit() end end end -- create a start menu menu = ponymenu.new( onMenu, { align = "center", font = "RobotoMono.ttf", fontSize = 32 }) menu:add("Play") local tmp = "lives:"..tostring(selectedOptions.lives) menu:add("Lives: 1,Lives: 2,Lives: 3,Lives: 4,Lives: 5,Lives: 6,Lives: 7") menu:set(tmp) local tmp = "rounds:"..tostring(selectedOptions.framesToPlay) menu:add("Rounds: 1,Rounds: 3,Rounds: 5,Rounds: 7,Rounds: 9") menu:set(tmp) menu:add("Quit") view:insert(menu) snap(menu) -- keys to toggle volume and music local function key(event) local phase = event.phase local name = event.keyName if phase == "up" then elseif name == "v" then snd:toggleVolume() if snd.volume \> 0 then menu:set("soundoff") else menu:set("soundon") end end end Runtime:addEventListener( "key", key ) end local function enterFrame(event) local elapsed = event.time end function scene:show( event ) local phase = event.phase if ( phase == "will" ) then Runtime:addEventListener("enterFrame", enterFrame) elseif ( phase == "did" ) then end end function scene:hide( event ) local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then Runtime:removeEventListener("enterFrame", enterFrame) end end function scene:destroy( event ) end scene:addEventListener("create") scene:addEventListener("show") scene:addEventListener("hide") scene:addEventListener("destroy") return scene

I’ve been through it with a fine tooth comb but cannot for the life of me figure out why it is doing it  :frowning:

Hmmm… I’m stumped.

Did you try to set it manually?  Like menu:set(“level:1”)

Maybe remove the colon?

You can always add a print() into the ponymenu lib and see what it’s trying to set?