Decided to make a game with controller support and figured I would need a whole lot more menu's to add to the game's functionality. Problem is, I have no idea how to make menu's without a boatload of if statements and integer values to keep track of what menu option I press and where to highlight the option I'm selecting. The other problem is that I don't know if there is any other way to do it than my brute force way.
You could try doing it in an event-based way and split up button-logic and menu-logic.
Maybe something like this, you have:
- A button-stage, holding button objects which know their size, appearance and name. Only the stage gets input and decides which button was pressed and which events to fire. It also has an render method that renders buttons according to their status (up/down/inactive). To add buttons you need to register them to your button-stage
- The events (ButtonPressed or so) contain the name of the button
- A button-listener interface that your game or screen class can implement to get events and react to them
LibGDX has a stage class, you can take a look at how they handle buttons and stuff, maybe that’s also helpful for you.
The way I’d do it (not being an OO type of guy) would be to have a simple set of parallel arrays. One would hold the name of the menu entry, another would hold it’s current value, and another pair to hold min and max values. When it comes to altering these values I’d just display the menu entries along with the current value. The user would be allowed to move up and down (you’d need a variable to hold the pointer of where you are) and left and right would change the current value as long as it’s not outside the min and max values. Every time you need to use one of these values in your program you’d just access the current value in the array. To make it more readable in the code you could have nice final values that point to the correct entry ie WAIT_TIME. This would only store int values but that’s usually all you need. It’s also very easy to add new items as you need them.
final int MAX_SETTINGS = 20;
final int WAIT_TIME = 0;
final int DRAW_DISTANCE = 1;
...
String SettingsMenuName[] = new String[MAN_SETTINGS];
int SettingsCurrentValue = new int[MAN_SETTINGS];
int SettingsMin = new int[MAN_SETTINGS];
int SettingsMax = new int[MAN_SETTINGS];
...
int SettingPointer = 0;
...
sleep( SettingsCurrentValue[WAIT_TIME] )
...
Mike
Parallel arrays are a recipe for headaches.
You haven’t told us what framework you’re using, what deployment targets you have, etc. There are a hundred different ways to make a menu, but they all depend on what you’re doing.
Do you want to go to the first menu item after the last one? Maybe you can use circular array index here.
index = (index + 1) % array.length;
This piece increases the array index, i.e., the index of the option of menu stored in an array, and if it exceeds the maximum index, it goes back to 0 since we are taking the modulus by the length of the array.
index = (index + array.length - 1) % array.length;
This piece decreases the array index. If the index goes past 0, then it goes to array last index, length - 1. This is an option too.
most things that are convoluted in source code can be manageable in external files. write your menu structure in xml, json or csv and simply convert it into objects (nodes), which have parents and children, dimensions, etc. then add some state to each node, attach an event handler, all driven by the data in the external file. you more or less are creating a scene-graph now with a basic layout manager. now that we arrived at that conclusion, it is time to consider looking at libraries that already provide this functionality… :point: (or not, either way works out pretty quickly)
Whenever I find myself using parallel arrays, I refactor ASAP to a list of objects.
Regarding menus, a big list of if-else is ugly but it gets things going. The next step for me is to wrap each if in an object with a functional interface, and then put those objects in a map keyed by the keystrokes.
I have decided (in thought) to treat each menu item like an entity. Each entity having the same “do” method that is called when I execute it. These entities are also in arrays seperated by the menu they are in. So I have a menu_ShipCreation array, menu_menuSelection, array etc. This is in thought because to do this I would need a seperate class for each individual menu option. So that pretty much gets thrown out the door. Unless there is a way to change the contents of a method from outside the class.
My mind is thinking something along the lines of this for my previous reply.
if(assetManager.update()){
Timer.schedule(new Task(){
@Override
public void run() {
core.setScreen(core.playScreen);
}
}, 1);
}
I want to understand how it is possible for me to add the functions I want in a pre-made method and have the method work with it. This is pretty much what’s been bugging me for a good while because I don’t understand how it works, I just use it because it does.
You still haven’t told us what you’re using or how you’re planning on deploying.
But rolling your own GUI sounds like a pain in the neck, especially when there is probably a library that handles all of that for you. That’s why I’m asking about what you’re using and how you’re deploying.
LibGdx, im trying to use scene 2d. Trying because I never used it before. All this skin, json, and everything about it seems extremely confusing. Couldn’t even make a scroll pane for my main menu as a changelog.
Getting a better idea of your skill level and understanding of LibGDX I recommend checking out this UI / level editor. It works w/ LibGDX and looks neat.
http://overlap2d.com/
Have no idea how that will help me create menu’s
A few useful Stage2d/UI tutorials here:
Overlap2D is a “menu machine” and level editor. Check all the videos out on YouTube like this; just search for “Overlap2d”
https://www.youtube.com/watch?v=Z5lfUZeqcq0 Granted some of the videos are a year old now and they did a big overhaul of the editor runtime.
It exports all of the assets and configuration to a JSON file then has a runtime to load everything for you and you hook up actions to the buttons, etc. There are plenty of videos. I don’t use it, but it looks neat especially if you are new to LibGDX…
Well, google is your first stop then. Try googling “libGDX gui” or “scene2d” or “overlap2d” for a ton of resources. Go through their tutorials and see how they work.
These libraries exist so you don’t have to “brute force” all of the UI logic yourself. The answer to your original question is: use one of these libraries.
I once made a mistake of creating my own menu system. After that I’ve always used other libraries which does the same job with less effort. My favorite one being Scene2D at the moment. I should give Overlap2D a try. Maybe in the next project
So all in all what I’m trying to say is the same as @KevinWorkman. Try to Google for other UI libraries. My recommendation would be Scene2D since there are some nifty tutorials for it.
Gamesfromscratch youtube channel covers the Scene2D usage pretty well. Maybe you should start with these if you have the time. They also have a good website with example code.
The site: http://www.gamefromscratch.com/post/2013/11/27/LibGDX-Tutorial-9-Scene2D-Part-1.aspx
Scene2D UI tutorial video:
ELkqiMpvMLA