Log In  

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 ?

P#107599 2022-02-24 16:00 ( Edited 2022-02-24 16:11)

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?

P#107600 2022-02-24 16:24

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:

Cart #sezepoyuga-0 | 2022-02-25 | Code ▽ | Embed ▽ | No License

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.

P#107619 2022-02-25 03:42 ( Edited 2022-02-25 03:43)

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
P#107621 2022-02-25 04:47

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:

Cart #ranatemepo-0 | 2022-02-25 | Code ▽ | Embed ▽ | No License

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 ?

P#107623 2022-02-25 05:17 ( Edited 2022-02-25 05:18)

@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.

P#107625 2022-02-25 07:32

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.

Cart #wewekegafa-0 | 2022-02-25 | Code ▽ | Embed ▽ | No License

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
P#107645 2022-02-25 17:17 ( Edited 2022-02-25 17:43)

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!

P#107659 2022-02-25 21:08

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.

P#107661 2022-02-25 21:52

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.

P#107664 2022-02-25 22:37 ( Edited 2022-02-25 22:41)

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 ?

P#107665 2022-02-25 22:43 ( Edited 2022-02-25 22:53)

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
P#107686 2022-02-26 09:06 ( Edited 2022-02-26 09:09)

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.

P#107702 2022-02-26 20:18 ( Edited 2022-02-26 20:18)

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.

P#107760 2022-02-27 19:05 ( Edited 2022-02-27 19:10)

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.

P#107762 2022-02-27 19:20
1

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.

P#107804 2022-02-28 08:26 ( Edited 2022-02-28 08:27)

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.

P#107832 2022-02-28 19:07

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 07:42:10 | 0.045s | Q:41