Mario and I have been refactoring the scene2d package. This is our 2D scene graph, which is useful for simple games and complex GUIs. If you already use scene2d, updating to the latest SVN may cause a few compilation errors in your projects. We don’t make API changes lightly, so please bear with us as the library improves.
Most of the changes are for the input system, which is now easier to use. Actor has these methods:
1 2 3 4 |
public abstract Actor hit (float x, float y); public abstract boolean touchDown (float x, float y, int pointer); public abstract void touchDragged (float x, float y, int pointer); public abstract void touchUp (float x, float y, int pointer); |
When a touch goes down, the Group class calls hit() on each child. If a child returns non-null then it was hit and touchDown() is called on the child. If this returns true, it means that the event has been consumed and no other children should be tried. It also means that if no other actor is “focused”, the child gains focus. Being focused means that the usual system just described will be bypassed and the focused widget receives all touch events. When a touchUp occurs, the focus is lost. This mechanism allows individual actors to easily handle complex touch events.
Another important change happened to Group. This class is an Actor that has children. When a group is rotated and scaled, its children are rotated and scaled. This is the main reason to use a scene graph and it is very powerful. The cost is that every frame each group does matrix transformations which use between 27 and 108 multiplications. This is not an issue for most games, as there is rarely a need for more than a few nested groups. However, when using the scene graph to create GUIs, groups are used to layout their children and it is easy to have a dozen or more nested groups. Since it is rare to use rotation and scale in a GUI, we added a boolean named “transform” to Group. When set to false, no matrix transformations will be done. Just be sure not to use rotation or scale on a group that has transform set to false!
As a result of the Group change, TableLayout is now more efficient. Feel free to nest tables to your heart’s content!
Skin saw some major changes. It used to be serialized by hand written XML (reading only). It is now serialized with our fancy automatic JSON serialization (reading and writing), with a fraction of the old code. Besides being good exercise for the JSON stuff, now that skin supports both read and write, some sort of editor may be in the works. A skin file now looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ resources: { com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: "default.fnt" }, com.badlogic.gdx.graphics.Color: { green: { a: 1, b: 0, g: 1, r: 0 }, white: { a: 1, b: 1, g: 1, r: 1 }, red: { a: 1, b: 0, g: 0, r: 1 }, black: { a: 1, b: 0, g: 0, r: 0 } }, ...more stuff... }, styles: { com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { default: { font: default-font, fontColor: white } }, ...more stuff... } } |
You’ll notice this is only similar to JSON (has no quotes). This is because our JSON stuff now has multiple modes: JSON, JavaScript, and the “minimal” format above. The minimal format is easier on the eyes, and if the data is only going to be read by libgdx, it really doesn’t matter if it follows the JSON spec.
Anyway, there are two parts to a skin. The “resources” section describes a bunch of colors, fonts, texture regions, nine patches, etc. The “styles” section describes a bunch of objects that use the resources. Above you can see a BitmapFont named “default-font” is defined, as well as a few Colors. Next, a LabelStyle named “default” is defined that references the font “default-font” and the color “white”. Here is some scene2d code to use this stuff:
1 2 |
Skin skin = new Skin(skinFile, textureFile); Label label = new Label("Some Test", skin.getStyle("default", LabelStyle.class)); |
The skin is completely extensible, you can use your own classes in the skin file to define any kind of resources or styles you want. The serialization happens automatically, thanks to the Json class, so you don’t have to add any special code to your classes.
The TableLayout SVN repo is now linked via the libgdx repo. This means a couple package names have changed. There are also a few new additions. GestureDetector detects tap, long press, fling, pan, and zoom touch events. FlickScrollPane is a scrollable area that works great on touch screens.
TL;DR: Return true from touchDown() if you handled the event and want to receive touchDragged and touchUp events. Use Group.transform = false if your group doesn’t use rotation or scale. Skin changed and is awesome. Use the JSON shit, it rocks!