12
\$\begingroup\$

Note: I plan on making my own GUI system. It will be good for learning, lightweight, only have bits I need, ties in with the game, etc.

I was thinking about how to do it. The elements I mean are:

  • Radio buttons
  • Enter text here boxes
  • Buttons
  • Sliders
  • Checkboxes

I'm not looking as to how to make them, yet. But more of how they would go.

Idea

I would have each state that needed stuff, so almost all, have a container of Elements. Each Element is-a GUI piece.

These each have position, a graphic, etc.

The bit I get more stuck on is the logic of them.

My idea for that, to allow for modularity and simplicity was to avoid a MainMenuStartButton; a OptionsOneBackButton, etc. and instead be able to do Slider slider1; or Button start;.

Instead, each would have a boost::function to a function in a GUI namespace, such like Gui::StartButtonClick, or GUI::ColourSliderHover.

I was just wondering whether this would be exceptionally slow or not.

And for that matter, is there any easy, simple way of doing GUI for games? No Qt, wxWidgets or anything.

\$\endgroup\$

9 Answers 9

14
\$\begingroup\$

GUI isn't an easy or simple problem, especially when you get into games and their desire to have dynamic, interesting menus.

One "easy" thing you can do is try to use middleware. There's a question on that here.

If you're going to roll it yourself, there are a few things I would suggest.

  • GUI elements generally have a "parent", either another GUI element or a "window", or something like that. Either by pointing up or having the parent point down means you can set state/position/etc on everything that's a child.

  • You can build GUI elements by composition. A lot of widgets have labels (pretty much all of them), and it might make sense to make the concept of a label a component or a child of your other UI elements than copy/pasting the code or trying to inherit from a base class with label functionality.

  • A lot of so-called specialized widgets are just buttons in disguise. Checkboxes are just buttons with states and special images. Radio buttons are just checkboxes that have meta-state (one and only one is active at any given time) with other radio buttons. Use this to your advantage. In one game I worked on, "checkboxes" were done with regular buttons entirely through scripting and art.

  • For your first project, consider taking the more direct route. Yes, make your actionable events delegates and assign what you need on element creation (i.e. onMouseButtonDown, onMouseButtonUp, onHover etc), but consider just hard coding what you want to happen otherwise (i.e. hover color changes, button press sounds) until you get something functional. Once you're at that point, consider making that behavior data (i.e. have a variable on button for "press sound", or maybe consider having components that your UI elements use to define behavior that you just attach to them when you create them.

  • delegates aren't that slow, you probably won't have so many widgets that it would be an issue, and menu code generally isn't that high impact anyway. I wouldn't worry too much about performance at this point in the game. Don't pick naive algorithms and profile once you get your code up and running.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ For more complex GUI stuff you'll need some sort of layout-management pretty soon. Basic layouts like HBox and VBox are much easier to use than positioning all elements with absolute coordinates. Example: web.archive.org/web/20100410150433/http://doc.qt.nokia.com/4.6/… That makes your GUI easier to use, but not so easy to implement ;) \$\endgroup\$
    – bummzack
    Aug 7, 2010 at 8:29
8
\$\begingroup\$

There have been some really interesting breakthroughs in mainstream UI toolkits over the past few years. Game UIs have been evolving too, but at a somewhat slower pace. This is likely because developing a full-featured UI subsystem is a significant undertaking in itself, and it's difficult to justify the resource investment.

My personal favorite UI system is the Windows Presentation Foundation (WPF). It really takes the potential for UI differentiation to the next level. Here are some of its more interesting features:

  1. Controls are "look-less" by default. A control's logic and visual appearance are generally decoupled. Every control ships with a default style and template, which describes its default visual appearance. For instance, a button may be represented as a rounded rectangle with an outer stroke, a solid color or gradient background, and a content presenter (to present the caption). Developers (or designers) can create custom styles templates which change the appearance and (to an extent) the behavior of a control. Styles can be used to override simple properties of a control, like foreground/background color, template, etc.; templates change the actual visual structure.

  2. Styles and templates may include "Triggers". Triggers can listen for certain events or property values (or combinations of values) and conditionally alter aspects of a style or template. For instance, a button template would generally have a trigger on the "IsMouseOver" property for the purposes of changing the background color when the mouse hovers over the button.

  3. There are a few different "levels" of UI elements ranging from lighter weight elements with minimal functionality to full-blown heavy-weight controls. This gives you some flexibility in how you structure your UI. The simplest of the UI element classes, UIElement, has no style or template and only supports the simplest of input events. For simple elements like status indicators, this functionality might be all you need. If you require more extensive input support, you can derive from FrameworkElement (which extends UIElement). Traditional widgets generally derive from Control, which extends FrameworkElement and adds custom style and template support (among other things).

  4. WPF uses a retained, scalable, resolution-independent vector graphics model. On Windows, WPF applications are rendered and composed using Direct3D.

  5. The introduction of WPF included a new declarative programming language called Xaml. Xaml, based on Xml, is the preferred language for declaring UI "scenes". It's actually pretty slick, and though it may appear similar at first glance, it's fundamentally different from existing languages like XUL (and much more powerful).

  6. WPF has a very advanced text subsystem. It supports most if not all OpenType font features, bidirectional ClearType antialiasing, subpixel positioning, etc.

"Ok, great, now how is this relevant to game development?"

Back when WPF was still in development (and known as "Avalon"), I was taking a video game design course at Georgia Tech. My final project was a turn-based strategy game, and I wanted a very capable UI. WPF/Avalon seemed like a good route to go because it had a complete set of full-featured controls and it game me the capability to completely change the look and feel of those controls. The result was a game with a beautiful and crisp UI with the level of functionality that you normally only see in full-fledged applications.

Now, the problem with using WPF for games is that it's fairly heavy-weight and renders in its own "sandbox". By that, I mean there is no supported way of hosting WPF within a Direct3D or OpenGL game environment. It is possible to host Direct3D content within a WPF application, but you will be limited by the framerate of the WPF application, which is generally lower than you would want. For some types of games, like 2D strategy games (screenshot of my current WPF game project), it could still work great. For anything else, not so much. But you could still apply some of WPF's more compelling architectural concepts in developing your own UI framework.

There is also an open-source, unmanaged C++/Direct3D implementation of WPF called "WPF/G (WPF for Games)"](http://wpfg.codeplex.com/) that is specifically designed for use in games on both Win32 and Windows Mobile. Active development appears to have ceased, but the last time I checked it out, it was a rather complete implementation. The text subsystem was the one area that was really lacking compared to Microsoft's WPF implementation, but that's less of an issue for games. I would imagine that integrating WPF/G with a Direct3D-based game engine would be relatively straightforward. Going this route could provide you with an extremely capable, resolution-independent UI framework with extensive support for UI customization.

Just to give you an idea of what a WPF-based game UI might look like, here's a screenshot from my pet project:

Screenshot from my ongoing WPF-based game project

\$\endgroup\$
1
  • \$\begingroup\$ NoesisGUI uses WPF. It's pretty good but I don't know WPF and I find it a pain to learn. I would prefer a web stack approach personally. \$\endgroup\$
    – user441521
    May 29, 2015 at 19:39
2
\$\begingroup\$

I would go for an immediate GUI, like this: http://code.google.com/p/nvidia-widgets/

The nVidia widgets are based on IMGUI (Immediate GUI) from MollyRocket.

I think that's about as simple as a GUI can ever get.

All depends on what your needs are.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Simple yes, and ideal for quick debug work or prototyping, but the amount of coupling between the UI and your game logic in Immediate GUIs scares me. \$\endgroup\$
    – tenpn
    Aug 1, 2010 at 20:37
2
\$\begingroup\$

In the game I'm working on, we have our own custom GUI framework. I've found it to be very simple, but still doing everything I want it to do. I don't know whether it's a "pattern" that many others use, but it works well for us.

Basically, all the buttons, checkboxes, etc. are subclasses of the class Element; and elements have Events. Then we have CompoundElements (which are themselves a subclass of Element), which contain other elements. In each cycle, three methods are called: processEvent(event), tick(time), and draw(surface). Each CompoundElement then calls those methods on its child Elements. In those calls (particularly the processEvent method), we fire off any relevant events.

All of this is in Python (a much slower language than C++), and it runs perfectly fine.

\$\endgroup\$
2
\$\begingroup\$

If you're going to need fairly sophisticated UIs, the best choice is probably to just embed a HTML renderer - you get all the common UI primitives you are used to, and you can trivially add complex UI to your game that will behave the way users expect, look great, and run fast (because browsers have pretty optimized rendering pipelines at this point).

There are a few libraries out there for embedding Webkit in games: Berkelium is the one I recommend, and I hear Awesomium is pretty good (used by EVE Online) and so is CEF (used by Steam). You can also try embedding Gecko - it's a lot harder to do but has some cool advantages as well. I'm currently using Berkelium for all my game UI (it replaced a combination of custom UI elements and native UI, and dramatically reduced the amount of code I had to write to get things running).

\$\endgroup\$
1
  • \$\begingroup\$ ^ This 100%. I'm saddened by the lack of good web stack for game implementations out there. The web stack is brilliant for UI and needs to start being more common in all games for their UI. So far the libraries I've tried to work with were a pain in the arse to implement or aren't 100% true html/css/javascript. I'm currently looking at Coherent Labs and it's looking promising but it costs a fair amount, but does have indie versions for a couple engines. \$\endgroup\$
    – user441521
    May 29, 2015 at 19:37
2
\$\begingroup\$

Make sure you actually need a sophisticated GUI system for your game. If you're making a computer RPG then obviously it will be a requirement; but for something like a racing game, don't overcomplicate things. Sometimes just rendering textures (custom button images) and having some "if" statements with hard-coded coordinates in your input function can get the job done. A game state machine (FSM) helps with this simple approach. Or, somewhere in the middle, forget the complicated hierarchy and scene graph approach and just have a "Button" class which packages the above-mentioned texture and input checks into simple function calls, but doesn't do anything complicated.

Nailing down your requirements is important. If you're unsure, just remind yourself YAGNI.

\$\endgroup\$
1
\$\begingroup\$

Here's one example (source code and all) of a GUI built for OpenGL, specifically for Slick2D called Thingle which is a port of Thinlet.

Another GUI for Slick2D was SUI that you might want to check out.

I'd follow these examples and go with an XML driven GUI. Although these projects are old/dead, you might be able to pick up some ideas from them.

\$\endgroup\$
1
\$\begingroup\$

I think one of the best ways to "figure it out" would be to have a look at how highly developed GUI frameworks work, such as Windows Forms in .NET.

For example, they are all Controls, which have a location, size, list of child controls, a reference to its parent, a Text property for whatever the control may use it for, as well as various overridable functions and predefined actions.

They all contain various events such as Click, MouseOver and Resizing.

For example, when a child control is changed, it sends a notification up the chain that its layout has changed, and all parents then call PerformLayout().

As well, auto-sizing and auto-arranging are common features of these GUIs, allowing programmers to simply add controls and the parent controls adjust or arrange them automatically.

\$\endgroup\$
1
\$\begingroup\$

For interests sake I thought I would throw out Scaleform. Basically the artists can use illustrator, photoshop etc, then the UI designer uses Flash to layout all the interactivity. Then Scaleform transforms it into code for your engine (well thats my understanding of it as I have not used it). Crysis Warhead used this system for their lobby.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .