I was wondering if there was a solution to this:
menuitem(1,c, function(b) if (b==2) then function() c=c+1 return true end end end ) |
Now I know I can create a new function to return true, however is there a way do it internally within menuitem() itself ?
What are you trying to achieve?
That snippet creates a menuitem callback that returns a function, but the menuitem callback should return a boolean.
Would moving the c=c2+; return true
into the menuitem callback itself be the answer?
Hi @dredds. Thanks for writing.
I guess what I'm trying to do really is see if it's possible to have a function that returns TRUE for arrow key reading inside the same function you use for menuitem().
See, this code works:
function _init() cls() c=0 end function _update() menuitem(1,c, function(b) if (b==2) then menu1() end end ) end function menu1() c=c+1 _update() end |
Press "P" to bring up the system menu. Press the RIGHT arrow key on the zero and it increases by 1 without exiting the menu. This to me is quite exciting.
So I want to merge menu1() inside of the menuitem() command and have it run just the same way - but I don't know how to do so without creating a uniquely separate function.
Not sure if this is exactly what you're asking, but this works for me:
function _init() cls() c=0 end function _update() menuitem(1,c, function(b) if (b==2) then c=c+1 _update() end end ) end |
OK, @picoter8, I did not think you could call _update()
inside _update()
without creating a stack overflow.
I'm remembering another part of the problem. The SCREEN does not update. Try this, based on your work:
function _init() cls() c=0 end function _update() pset(rnd(128),rnd(128),rnd(15)+1) domenu() end function domenu() menuitem(1,c, function(b) if (b==2) then c=c+1 cls() domenu() end end ) end |
How do I get the screen to clear when pressing the RIGHT arrow key on the digit yet continue to run the menu without any screen flicker and to maintain the current menu position where the numbers increase ?
@dw817
That code isn't calling _update() from _update(). It's calling _update() from the internal menu code.
As for not having the flicker, I've experimented with calling the menu again and suppressing it as well as calling the menu again and messing with the button state, but neither seems to work. I think the only way would be to manually draw the menu after clearing the screen, then clear it again when the menu goes away.
I like all of these ideas yet @freds72's was an interesting one. Where dja go man ? You saw it was me and deleted your answer ? Feel the love. :) The idea of using DRAW(), but that can be used in a different way - it doesn't work here to update the screen.
I finally found a solution, it's an ugly one. Use FLIP()
inside your function. It updates but it does take away the menu temporarily. Where you can use this anywhere I like the idea of my menus being reinstated in a separate function.
function _init() cls() c=0 end function _update() pset(rnd(128),rnd(128),rnd(15)+1) domenu() end function domenu() menuitem(1,c, function(b) if (b==2) then c=c+1 cls(c) flip() -- force to appear! domenu() end end ) end |
If I understand what you’re asking then you don’t need any tricks. The parameter passed to the menuitem callback identifies which button the user has pressed while the menuitem is selected, and the callback can process the button press and then control whether to keep the menu open or close it by returning true or false.
Have a look at how I’ve implemented the music on/off menu item in Squishd!
I'm looking at your code, @dredds:
function set_music(on) music_on = on if on then music(0, 0, 1) else music(-1) end menuitem(2, "music ⬅️ " .. (on and "on " or "off") .. " ➡️", function(input) local changed = input == 1 or input == 2 if changed then set_music(not music_on) end return changed end) end |
What's interesting is every time you press the LEFT or RIGHT arrow key on any menu option, after a few times of this the screen changes, yet I can't seem to recreate this effect in my own code.
Your game is also not using _update() nor _draw() I'm wondering if this is why.
The game uses both _update60 and _draw.
When you say the screen changes, you mean the menu changing? Or the screen drawn behind the menu?
If it’s the menu changing that is because the set_music function calls menuitem to create the menu item for changing the music setting, and the callback to the menuitem calls set_music when the user presses the arrow key, which then recreates the same menuitem but with different text.
Ohhh, you renamed it, @dredds ! I was not expecting that. I was looking for the exact function names with function
in front, not new variable names. You have quite a bit going on there, I may never understand it all. :)
You may, however, have given me the answer to a different problem regarding frame rate, let me see ...
. . .
No, not that. The curious arrangement you have in your code though, still does run bits of it when you select LEFT or RIGHT in the menu. I'm - not going to be able to decipher all of your code, can you please write me a simple sample of code that shows this. That is something that plots pixels on the screen for every time you press LEFT or RIGHT in a menu without removing the menu ?
Here's a commented version that removes some unnecessary variables and makes the logic more explicit.
function _init() -- We call set_music(true) at the start of the program to -- turn the music on and create a menu item to -- turn the music off set_music(true) -- and other initialisation logic here ... end -- set_music(turn_music_on: Boolean) -- -- Turns music on or off, and sets up the menu item on the pause -- menu to toggle the setting (e.g. to turn the music on if it was -- turned off, or off it it was turned on). -- -- Usage: -- set_music(true) : turn the music on -- set_music(false) : turn the music off function set_music(turn_music_on) if turn_music_on then -- start playing the music from pattern zero music(0) -- set up menu item 2 to turn the music off menuitem(2, "music ⬅️ off ➡️", function(input) -- only respond to the left and right direction buttons local left_or_right_pressed = input == 1 or input == 2 if left_or_right_pressed then set_music(false) end -- If the player pressed the left or right direction buttons, -- return true to keep the menu on screen, otherwise return -- false to hide the menu when they press the X or O button -- or press the Pause button again if left_or_right_pressed then return true else return false end end) else -- stop playing the music music(-1) -- set up menu item 2 to turn the music back on menuitem(2, "music ⬅️ on ➡️", function(input) local left_or_right_pressed = input == 1 or input == 2 if left_or_right_pressed then set_music(true) end if left_or_right_pressed then return true else return false end end) end end |
No, @dredds. This is not working for me:
function _init() -- we call set_music(true) at the start of the program to -- turn the music on and create a menu item to -- turn the music off set_music(true) -- and other initialisation logic here ... end function _update() pset(rnd(128),rnd(128),rnd(15)+1) end -- set_music(turn_music_on: boolean) -- -- turns music on or off, and sets up the menu item on the pause -- menu to toggle the setting (e.g. to turn the music on if it was -- turned off, or off it it was turned on). -- -- usage: -- set_music(true) : turn the music on -- set_music(false) : turn the music off function set_music(turn_music_on) if turn_music_on then -- start playing the music from pattern zero music(0) -- set up menu item 2 to turn the music off menuitem(2, "music ⬅️ off ➡️", function(input) -- only respond to the left and right direction buttons local left_or_right_pressed = input == 1 or input == 2 if left_or_right_pressed then set_music(false) end -- if the player pressed the left or right direction buttons, -- return true to keep the menu on screen, otherwise return -- false to hide the menu when they press the x or o button -- or press the pause button again if left_or_right_pressed then return true else return false end end) else -- stop playing the music music(-1) -- set up menu item 2 to turn the music back on menuitem(2, "music ⬅️ on ➡️", function(input) local left_or_right_pressed = input == 1 or input == 2 if left_or_right_pressed then set_music(true) end if left_or_right_pressed then return true else return false end end) end end |
If you run the above code you will see dots appear on the screen. If you select the music on or off a new dot does not appear.
In your original game:
https://www.lexaloffle.com/bbs/?tid=46656
If you pause it and press LEFT or RIGHT several times even if not on the LEFT or RIGHT option, the animation will continue one frame in the background.
This is what I am hoping to reproduce in as little code as possible. Where you can pause the program. Press LEFT or RIGHT and a new random dot will appear on the screen behind the menu without affecting the menu.
Your game does this, where animation continues despite being in a menu. It is unique and interesting feature and I suspect others could use this helpful knowledge too.
Oh. I didn’t understand that you wanted animation on the display behind the pause menu to happen. I thought you just wanted the menu itself to change.
I have no idea why animation should continue in Squishd! while the pause menu is visible. I did not code anything to do that and would not expect it to happen given what I did write and the way I understand the pause menu to work. Maybe it’s a bug in Pico-8.
Update: interestingly, this happens even if I press left or right on the “Clear Highscores” menu item for which I haven’t written any code to handle different button inputs. So maybe it is a bug.
If it's a bug though, @dredds. I want it as a feature. I can definitely see how that could be useful.
You could select something from the menu and have a graphic panel above the menu that updates accordingly.
I wish you could isolate the miracle you did as I think this would be of use to other coders as well.
The behaviour you observed (a frame of animation happening whenever you interact with a pause menu item) does not happen in the Pico-8 app, only in the web player. So it looks like a bug in the web player, not expected behaviour.
Ohh ... That's critical to know, @dredds. Wow. Ratzy ... OK so it is abnormal behavior after all. No wonder I couldn't reproduce it just through my offline code.
Hmm ..., well @zep if you can make this an optional thing, maybe an obscure POKE that lets you update the screen behind a normal MENU, that would be most useful.
[Please log in to post a comment]