-
Notifications
You must be signed in to change notification settings - Fork 35
From the Ground Up 01: Buttons
Now that you are an expert with layout, are you ready for a deep dive into Scene2D.UI Buttons? Learn about Buttons, ImageButtons, and TextButtons here!
The Button is the foundation of any interactive user interface. You can get away with a simple menu composed entirely of buttons in most games. The Button class is a specific kind of button that has no text which reacts to user clicks. TextButton, ImageButton, and many other classes are derivative from this class.
Buttons are largely composed of Drawable elements. The "up" state is the normal view of the button.
The "over" state is what the button looks like when the mouse is hovering over the button. This is optional, though it is highly recommended for Desktop and HTML5 backends. It is nearly meaningless on mobile platforms unless the user has a mouse attached. Notice the subtle, darker edge to the button. Use a technique of your choosing to illustrate the difference from the normal state.
The "down" state describes how the button looks like when it's pressed. This is optional, though there isn't much reason to not support this state. This example is darker and looks like it's pressed in to sell the appearance.
The "disabled" state isn't always necessary, especially if you don't plan on ever disabling the button in game. When it's important to denote that the button cannot be touched, you can make it slightly transparent, washed out, or darker. See Tinted Drawables.
"pressedOffsetX" and the like will appear to not do anything. This actually affects the contents of the button, which is more important for other kinds of buttons. See TextButton for example.
A normal button does not have any value for "checked" or "checkedOver". If you want the button to stay depressed after it's clicked on, you usually set the "checked" state to the same drawable as your "pressed" state.
For extra flair, you can have a "checkedOver" state which is just a slight variation.
You can use this technique to make a switch button that shifts from yes to no, or on to off.
The human brain is easily fooled by UI elements. Even though monitors only display two dimensions, we have trained ourselves to see buttons as having "depth" whenever they have a drop shadow. This signals to the user that this element should be clicked on. Often times this is further conveyed with an imaginary light source from above, causing a kind of highlight or gradient. Making the button actually move through the pseudo-3D space sells the effect even more.
Round corners are a sophisticated kind of polish. They are more friendly to users, though it depends on the theme you are going for. If you have a futuristic action game, you might want buttons with sharp corners for an aggressive feel. Kids' games might want round, soft buttons.
Any kind of button needs to adapt to different sizes. These buttons with rounded corners or lined edges need to be NinePatchDrawables
Animating a button is possible with the TenPatchDrawable class. Although animation takes added finesse, it really takes your UI to another level. See the Shimmer UI example
From libGDX version 1.9.9, a new feature is the "focused" state. With some added logic, you can make your buttons react to keyboard or controller input instead of just the mouse.
if (Gdx.input.isKeyJustPressed(Input.Keys.TAB)) {
stage.setKeyboardFocus(theNextButtonToBeHighlighted);
}
A full example is available with the Shadow Walker UI skin.
Because Button has no text or content, it's typically used as a kind of icon button. Use common symbols to represent functions like "mute audio" or "close the window". These don't necessarily need to scale, so regular TextureRegionDrawables are fine for this use.
In order for a button to actually do something when you press it, you need to use a ChangeListener. ChangeListener is a common type of listener used throughout Scene2D.UI that is triggered when a widget is interacted with. Do not use a ClickListener for this purpose unless you like making puppies cry. ClickListener does not respect the disabled state of buttons.
Button button = new Button(skin);
root.add(button);
button.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
System.out.println("Hey, you clicked me!");
}
});
An underrepresented feature of Button is the fact that every Button is a Table. By extending Table, Button allows you to add anything you want in it. This gives you some flexibility in your design if you're making a kind of custom widget. These can be labels or images, for instance. When the convenience of TextButton and ImageButton limit you, you should turn to this technique.
Button button = new Button(skin);
root.add(button);
Label label = new Label("First line", skin);
button.add(label);
button.row();
label = new Label("Second line", skin);
button.add(label);
TextButtons are composed of a basic button and a Label. Color is used to change the appearance of the text as the button is hovered over or pressed.
Create a basic font that is primarily white and set that as your "font" value. Change "fontColor" to tint the font to its normal color. "downFontColor" is the color when the button is pressed. "overFontColor" is the text color when the button is hovered over. You can even set checked color variants. I usually set "disabledFontColor" to a grey or slightly transparent color.
You can use the same techniques you learned above regarding ButtonStyle for the drawables in your TextButtonStyle. Keep in mind if you use a pseudo-3D approach, you have to adjust the content padding of your nine patch or set the "pressedOffsetY" to make it appear that your text has moved down with the button.
ImageButton is just like a Button, but it has an image inside. You can use these as a kind of icon button if you want. The advantage is that you can set the style to automatically change the image's appearance along with a background. Don't confuse the fields for the background ("up", "down", "over", etc.) for the image fields ("imageUp", "imageDown", "imageOver", etc.)
ImageTextButton combines the features of the TextButton and ImageButton. I often overlook this class because I would prefer to have more control over the layout of the images and text. See the articles on Image and Label.
Now that you've practiced with Button, you'll find that the rest of the UI widgets are pretty straightforward to deal with. All involve some combination of Colors, Drawables, and Fonts for the most part. It's the nuances of the code and design that set them apart. Continue with chapter 02 Checkboxes and Radio Buttons or return to the table of contents.
Getting Started
Windows
Linux
Mac
Features Manual
Colors
Fonts
Creating Bitmap Fonts
Creating FreeType Fonts
Creating Image Fonts
Drawables
Nine Patches
Ten Patches
Classes, Styles, and the Preview Panel
Custom Classes
Exporting
Importing
Saving / Loading
VisUI Skins
Tips and Tricks
TextraTypist Playground
Scene Composer
Scene Composer
Exporting a Scene
Modifying a Scene
Tutorials
Skin Composer Videos
From The Ground Up Series
Examples
Ray3K Skins