Is it just me, or does everyone's GUI code look like spaghetti?

As I write my GUI for my latest game, probably one of the most complicated GUIs I’ve had to write because it’s 100% mouse driven and has a bazillion buttons to press on the interface, I find my code becoming spaghetti. I was curious how you guys handle your GUI code? Mine seems to be turning into a stupid amount of booleans and if/else statement, for example, here’s my current state of my left mouse button:


if(input.isMousePressed(Input.MOUSE_LEFT_BUTTON)){
	//Toggle Menu tabs in and out
	if ((mouseX > rightHandAlignX+4) && (mouseX < rightHandAlignX+12) && (mouseY > rightHandAlignY+144) && (mouseY < rightHandAlignY+182)){
		rightHandToggle();
		return;
	}
	if ((mouseX > leftHandAlignX+44) && (mouseX < leftHandAlignX+52) && (mouseY > leftHandAlignY+144) && (mouseY < leftHandAlignY+182)){
		leftHandToggle();
		return;
	}
	//Press buttons on right hand
	for (int x = 0; x < 2; x++) {
		for (int y = 0; y < 8; y++) {
			if ((mouseX > rightHandAlignX+16+(x*36)) && (mouseX < rightHandAlignX+49+(x*36)) && (mouseY > rightHandAlignY+31+(y*20)) && (mouseY < rightHandAlignY+48+(y*20))){
				System.out.println("You pressed button: "+((x*8)+y));
				//Light placement button
				if ((x*8)+y == 0){
					if (modePlaceLight){
						modePlaceLight = false;
						return;
					}else{
						modePlaceLight = true;
						return;
					}
				}
				//Place blood
				if ((x*8)+y == 1){
					if (modeBlood){
						modeBlood = false;
						return;
					}else{
						modeBlood = true;
						return;
					}
				}
				if ((x*8)+y == 2){
					changeTime("day");
				}
				if ((x*8)+y == 3){
					changeTime("night");
				}
			}
		}
	}

	if (modePlaceLight){placeLight(getTileX(), getTileY()); return;}	
	if (modeBlood){addBlood() return;}			
	selectEntity(getMouseOnMapX(), getMouseOnMapY());

Basically it’s seeing where the mouse is, the forloop just assembles a set of 16 “box areas” in an 2x8 pattern, when you click on it, it checks what box you pressed and enables whatever is under that button. Then, below, it just has a ton of boolean and if/else checks (only 2 for now, but that will quickly expand to about 20 when I have to check for all the other situations) then it goes to mini-methods that tell other classes what to do.

So, do you guys run into this problem with complex GUIs as well? It really feels like a huge tangled mess, because almost everything in the game will be tied to the right and left click mouse buttons, meaning it’s probably going to be a pretty long little section of code that sort of sprawls out in the right direction based on a ton of if/else and booleans.

Really, the GUI itself works great and even though it looks messy it’s not actually hard to code, it just feels wrong. So I was curious what other’s experiences have been coding their own custom GUIs.

Yes. I recognize this problem. Very Well. :slight_smile:

I wrote a game a couple of weeks ago with a messy GUI that I implemented afterwards. It became such a mess I decided to create a model for GUI’s to use for every game after that. But since I decided to rewrite the game I made with this new model, I ran into several problems. Using workarounds or complete code changes I was able to ‘fix’ these problems, but it cost me the cleanness-ish of the code (partially).

I think the main problem is that you start of coding a game, and then adding the GUI (menu’s etc.) elements. If you want everything to be compatible, you need to start by writing the framework for the GUI and it’s coöperation with the game itself.

So yes, for me: I recognize this problem. You’re not alone ;D

Fun parts going to see what my left mouse button code looks like when I add all the buttons currently planned, right now on screen is 29 buttons (and more on the way) that all need to react to the left mouse button in some way or another. Some open menus, some are toggles to place buildings, some are just GUI interface things like changing pages. All of them do their own thing, and really don’t have much to do with each other, but they’re all going to end up inside the left mouse button code one way or another, even if I give each button it’s own method the left mouse button will still end up looking something like this:

rightCategoryArrow();
leftCategoryArrow();
rightHandTab();
leftHandTab();
<>
mainMenuButton();
villagerButton();
heroButton();
barterButton();

…and so on and so forth… then shortly followed by about 2 dozen of these

if (someButtonOn){methodToRunOnClick(); return;}

Well the huge thing about keeping input code neat is completely separating it from the logic code. You can prevent spaghetti by having a boolean track your button presses and pushing all that code to the update method instead. That way, no nested loops need to be in the input method. Just my 2¢.

Yes! That is what I tried to do consistently. However everyones code is difference, so everyone will encounter different problems with different solutions that don’t always work by putting it into the update method (or something like that).

oh, that’s actually what I’m doing. The nested forloop doesn’t actually do anything functional related to the execution at all, it’s just shrinking the code down for detecting where the mouse is for the 16 right side buttons that are all lined up, then the IF statement is just seeing what button you’re over in the loop and executing the method attached to that button.

In this screenshot, on the right hand tab thats open, all that forloop is doing is driving the “if mouse is between X and Y do this” for all those solid black boxes (to be buttons someday), that way I dont have to rewrite the exact same code for all 16 buttons.

http://sixtygig.com/junk/InDev-2014-05-13-7.png

I’ve put a lot of effort into making UI code nice: DSL, visual editor, etc. The best thing I’ve come up with is: use a sane 2D scene graph that has the features needed for UIs (drawing, layout, events), use a flexible layout manager with a builder style API, and organize your code by separating it into 3 parts: creation, layout, and events. I can suggest scene2d.ui and TableLayout for the first two. You can see this example UI code for how it looks in practice. This code isn’t too bad, but could be organized slightly better. For complex UI code I usually have 3 separate methods for creation, layout, and events. It really makes a difference, as it is hard to make any sense of layout code when it is mixed with other things.

Maybe an example of what I mean would help…

http://www.java4k.com/index.php?action=games&method=view&gid=406#source

If you scroll all the way to the bottom, you’ll see that boundaries are checked in the logic, where the spaghetti code lives. The mouse input code is kept nice and tidy. It is a style choice, yes, but it keeps all clutter in one spot which may or may not be what you are going for.

There might not be any other solution for this, but realistically it makes no difference because the work has to be done somewhere. :-\

Ah, I see what you mean. I thought about doing something similar, and attaching the mouse to a method I’d keep somewhere else that handles all the GUI button clicking. At the very least it (visually) gets the code out of my controls/input area so it’s easier to read everything else there.

But like you said, the spaghetti eventually has to go somewhere anyway. It seems like a large majority of GUI code ends up like this, because you end up with a lot of similarly functioning buttons all under the same controls that are all just-different-enough you really can’t combine much of anything together… so for code as simple as detecting what button you’re hovering over and what method to run when you click on it can easily skyrocket to a hundred+ lines of code just for a dozen buttons.

The few examples I’ve found where people claimed to have nice GUI code were using other GUI libraries to assist them that, surprise surprise, are just spaghetti code in hiding because all the spaghetti is just hiding away in the library, and if they brought it out they’d have a similar mess anyway.

Look at how a 2D scene graph works.

Interesting, that’s very similar to what I wanted my final product to be, although I’m not using LibGDX. But at least it shows me that the “big picture” I wanted to eventually reach is possibly in the right direction. :smiley:

My GUI’s actual functionality is in it’s infant stage right now, mainly because I’ve spent the last 2 days mulling over how I wanted to do it while I worked on other things, and not doing much actual coding on it. I might try to mimic how Scene2d works, see if I can pull something together.

It shouldn’t. The code in the methods might run to that, but the code to dispatch them should be much simpler. Unless you have so many buttons that you need a BSP or quad-tree, you just need to register tuples of (x, y, width, height, strategy) and loop through them.

@pjt33 I agree, it shouldn’t

I just check every update where my mouse hovers over.

e.g.:

The code for your menu (GUI) would look like this:


public void update() {
for (Button b : buttons) {
b.hover(mouseX, mouseY);
}
}

and then the code for the button:


public void hover(int x, int y) {
if (x >= this.x && x < this.x + width && y >= this.y && y < this.y + height) {
// Do the hover stuff and things.
} else {
// Just do stuff you want to do when not doing the hover stuff and things.
}

:slight_smile:

I separate my buttons out into classes which extend from a superclass called Button. Button (the superclass) has a couple of methods, and is abstract:
update()
render() //not entirely relevant, shown for the sake of completeness
checkClicked()
abstract onClick ()

In the update method I check if checkClicked returns true, and if it does I fire off the onClick method, which every child implements. Obviously I then create child classes and fill in the onClick method. Then my GUI code is much simpler, all I have to do is create a list of buttons, position then, render them and then update them. I don’t need huge long if statement blocks and I become a happy person because GUIs suck :slight_smile:

Maybe that helps?

This worked pretty well for RainbowHippie, it was clean enough. One problem I ran into is that it quickly became necessary for my GUI elements to check eachother’s states. For example, we dont want button A working if screen B is active. Looking back, really the answer to that would have been implementing a finite stat machine. Here is a great look into how they can help make your life alot easier in certain circumstances : http://gameprogrammingpatterns.com/state.html

  • Break large functions/procs into smaller functions/procs
  • Code is usually easier to write than it is to read. Especially large code bases.
  • If you have lots of functionality, you will have lots of code.
  • Study functional programming in languages like Scala/Haskell, if you want some more advanced ideas on code elegance and organization.

Hmm, I handle this scenario by placing a clear “panel” over the controls I need disabled, then drawing the modal window/controls inside of that panel. It prevents user input events from reaching the disabled controls (modality) and makes swapping entire layers of the GUI in/out a breeze. Adding FSMs in this scenario would seem to be adding unnecessary complexity to a straightforward problem, at least on first consideration.

Anything GUI related scares the shit out of me tbh, soon as I start coding it, just becomes a tangled mess.

For checking if the mouse is hovering over something. Why not just use Rectangles and detect intersection? That’s what I do to make my custom buttons work.

Sorry, but I considered this ‘code’ funny enough to quote :-*

modeBlood = !modeBlood;

To make this post a little bit useful, I also used the Rectangle class and searched for an intersection.

button.intersect(Point mouse); //returns boolean