Simple Menu System
-
Dunno if we already have something similar, basic search turned up empty, so...
I found this great and easy way to do ingame menus. By "found", I mean I stole it :) I think from here, maybe someplace else, but definitely some Rust library.Anyway, the basic thing is this. In your usual GUI framework, menu entries, buttons and stuff are objects managed by the UI system, and you as a user attach data to show and code to execute when things get pressed. The problem is, Fuze does not have the capabilities to do any of that. But we do have function calls, 'ref', and structs. So one can turn the way a GUI works around:
- YOU are in control of the main UI loop
- Each UI element is a function call in that loop
- Data you want the UI element to modify is passed as a ref argument
- The function's return value tells you whether an element was activated
Here is a small project with a menu system implemented that way (taken from the Lightcycle game, simplified a bit):
Share code NXKZKGCM51
Should also be at https://fuzearena.com/catalogs/view/1467 , but isn't for some reason.A sample menu would be coded like
fuction testMenu() int number = 0 int color = 0 colors = ["red", "green", "blue"] menu = menuCreate() loop textSize(gHeight()*.1) menuBackground(menu) menuBegin(menu, "Main Menu") if menuItemInt(menu, number, "Number", 0, 10) then // a menu item where you can pick an integer number ... endIf if menuItemArray(menu, color, "Color", colors) then // a menu item where you can pick between elements of an array ... endIf if menuItem(menu, "Submenu") then // a simple menu item, return true if activated testSubMenu() endIf if menuItem(menu, "Done") then break endIf if menuEnd(menu) then break endif // ends the menu loop, returns true if the 'b' button was pressed update() repeat menuDestroy(menu) return void
Result:
The testSubMenu() function is just another such menu function:
fuction testSubMenu() text = "Boo" menu = menuCreate() loop textSize(gHeight()*.1) menuBackground(menu) menuBegin(menu, "Submenu") // text entry menu item. Allows direct entry over // an USB keyboard (with the limitation that the only control // key is DEL, doing backspace...) or the usual text entry box. // The boolean argument is passed to the multiline argument of that box. menuItemText(menu, text, "Text", false) if menuItem(menu, "Done") then break endIf if menuEnd(menu) then break endif update() repeat menuDestroy(menu) return void
Result of that:
You can extend the behavior of menu items by just writing new functions that call the old ones. The existing menu items already make use of that, with everything falling back to menuItemBase(), which handles the selection highlight and bookkeeping. And of course, you can code it using fancier text output. This implementation just uses the regular print functions, no blending effects, backgrounds or drop shadows. Those are exercises for the reader :) A good start probably would be to render into an image first.
-
Thanks for sharing this. My attempt to add a menu system to my big project was an absolute bust, so I very much appreciate what you’ve done here.
-
I'm actually trying to set one that draws over the rest with a sprite arrow and stuff. I'll see if this'll come in handy. It just might.