On this post I'll detail the most important changes. The first thing we should do is download the latest version of libgdx and replace the JAR and SO files in our projects. After doing that you'll notice that many compile errors will appear.

Important changes in scene2d

Getters and setters added
Using getters and setters is a simple best practice as it improves the encapsulation of behavior, but it could hinder the performance because these methods will be called several times for each rendered frame. I suggest you keep an eye on the FPS output of your game. For Tyrian it won't make a difference. If you'd like to read more about the advantages of using getters and setters, have a look at this question at stackoverflow.

Actions system rewritten
It's now even easier to combine actions because they can operate on the same properties of an actor. The syntax has also changed a bit, so instead of FadeIn.$(0.75f) we can statically import the action and use fadeIn(0.75f). The actions you can statically import can be found in com.badlogic.gdx.scenes.scene2d.actions.Actions.

Generic event system developed
Each actor has a list of capture and event listeners. Both listeners extend the generic com.badlogic.gdx.scenes.scene2d.EventListener. The capture listeners may intercept the events before they're handled by the event listeners. During this capture phase, the event is given to the root down to the target actor. If the event is not cancelled by a capture listener, the normal phase kicks in and the event is given to the target actor up to the stage's root. Given that, the following is possible:

Instead of querying the input mechanism to move our ship, we could just receive the input events as they happen and modify our actor accordingly (see com.badlogic.gdx.scenes.scene2d.ActorListener). I didn't see any event related to the accelerometer though, so let's stick to what we were doing;

We can also fire our own events. I'm glad to see this feature, otherwise I'm pretty sure we'd have to implement it ourselves;

We can create a hierarchy of event listeners, possibly extending one of the shipped listeners:

ActorListener: listens for input events, like keyDown/Up/Typed, enter/exit, touchUp/Down and so on;

ChangeListener: listens for change events, that is, when something changed in an actor;

ActorGestureListener: makes it easy to work with gesture events, like pinch, zoom and fling.

We can reuse event listeners by adding them to different actors.

Actions and the new event system
I was expecting to receive events as the actions started/stoped on some actor, but sadly it doesn't work that way.
In order to switch from the SplashScreen to the MenuScreen, we used to do something like this:

The Drawable interface
An abstraction was created to handle objects that know how to draw themselves: com.badlogic.gdx.scenes.scene2d.utils.Drawable. The following list shows all the currently shipped drawables, but of course you can also write your own:

EmptyDrawable: A good drawable to extend if you're planning to write custom drawables. Provides a rectangular drawable area but draws nothing.

TextureRegionDrawable: Wraps a TextureRegion, which is a rectangular area of a Texture;

SpriteDrawable: Wraps a Sprite, which describes both a texture region, the geometry where it will be drawn, and the color it will be drawn.

Animations and the new Drawable interface
Remeber we use a 2D animation to tilt the ship? The utility class we used (com.badlogic.gdx.graphics.g2d.Animation) still requires TextureRegions for the animation's frames. The problem is that the modified Image actor now requires a Drawable, and not a TextureRegion. So we'd better create a map whose keys are TextureRegions and the values, Drawables. This way we can avoid instantiating Drawables on demand, which would wake up the garbage collector sometimes, resulting in small freezes while playing the game. Have a look at the modified com.blogspot.steigert.tyrian.screens.scene2d.Ship2D code for detailed information.

Pool and Poolable: A pool of objects that can be reused to avoid allocation;

ReflectionPool: A customization of pool that uses reflection to build instances;

Timer: Schedules the execution of tasks in a platform independent manner;

Array: A resizable, ordered/unordered array of objects;

DelayedRemovalArray and SnapshotArray: Customizations of Array that handle concurrent modification in specific ways;

I suggest you take some time to view all classes under com.badlogic.gdx.utils. They can really save you hours of work.

Documentation is being rewritten
It already contains many useful information (check it out), but meanwhile I make millions of dollars with this blog. Have you clicked the ad banner today? :)

The new TexturePacker

The TexturePacker was completely rewritten. It's now said to be much faster, easier to use and most importantly, it packs images better. A new packing algorithm is being used, the MAXRECTS, created by Jukka Jylänki. Here is the official documentation for the updated version. From the related libgdx post:

Configuration: The underscore file name conventions are gone. File names can still have a numeric index, it is simply any numbers at end of the file name, before the file extension. To better control packing in various ways, a "pack.json" file can be placed in each input directory. This contains the JSON for the com.badlogic.gdx.tools.imagepacker.TexturePacker2$Settings object. Each directory inherits all settings from the parent directory and any property set here will override those.

Nine patches: Files with ".9" before the file extension are considered a nine patch file. The pixels around the edges are read and stripped off before packing the image. Once again, you can create nine patches with Android's draw9patch tool. The split information is stored in the pack file, enabling TextureAtlas to provide instances of NinePatch. The splits in the TextureAtlas file format are optional, so existing pack files are still compatible.

In Tyrian we'll add the pack.json file in tyrian-game/etc/images, and this file will hold the configuration values for the TexturePacker. You can play with some properties if you want to customize the output. The only non-default values I used were the "filterMin" and "filterMag", which I set to "Linear". I also removed the configuration directives from the raw images' names (e.g.: splash-image_l,l.png is now splash-image.png). To run the TexturePacker, we could execute the following command on the prompt:

But we can do it inside Eclipse by creating a Java launcher. I saved it under /tyrian-game/TyrianTexturePacker2.launch, so you can open it with your Eclipse like so: Run > Run Configurations... > Java Application > TyrianTexturePacker2.
That done we can use the TextureAtlas class like this:

Important changes in Table Layout

Remember our layout descriptors? Well, they're gone. The main argument for its removal was that most of the time we "have to fallback to the code to manage the UI". As I see, the controller (screen) will be even more coupled to the view. I'm sad with this change because I like to have the layout structure in separate files, but let's follow the updated TableLayout's documentation and modify our code. Now we have to do something like this:

Conclusion

Libgdx is not yet mature, so we should expect future refactorings like this one. But it's evolving quite fast and it already provides many features required for commercial game projects. This is the tag on the Subversion repository for this post, and I these are the commit differences from the previous revision.
Thanks for reading!

2012-06-25

Like in many other gaming frameworks, a 2D animation is just a sequence of static images (frames) shown with a certain speed, creating an illusion of movement. On this post we'll use an animation to make the ship tilt to the side it's moving.

Important changes made to the existing code:

Enabled the use of OpenGL ES 2.0 in the both launchers: TyrianAndroidLauncher and TyrianDesktopLauncher. Libgdx will fallback to OpenGL ES 1.x in case the 2.0 isn't available. This can bring your game some valuable performance enhancements as stated here (section: Choosing an OpenGL API Version).

The Ship2D class was modified as follows:

We'll be using a simple MAX_SPEED constant (given in pixels/second), instead of the previous MAX_HORIZONTAL_SPEED and MAX_VERTICAL_SPEED.

The moveShip method was simplified regarding its interpretation of the accelerometer values. I also created a VectorUtils class to remove many ifs from this method, making it easier to read.

A deceleration was added to make the ship stop flying when there is no user input. I won't go into details on this because on the previous post I wrote about acceleration, so you should be able to easily understand this modification. If you have any questions, just post it as a comment.

Using animations

In libgdx we use the com.badlogic.gdx.graphics.g2d.Animation class to perform 2D animations. This class holds the animation's frames (in the form of TextureRegion instances) and sets the time each frame should be shown. This utility class performs no drawing at all. After it's created, we'll make use of the following method:

public TextureRegion getKeyFrame(float stateTime, boolean looping)

This method retrieves the next frame to be drawn. Let's understand each parameter:

float stateTime: this is an accumulator value that represents the time elapsed since the start of the animation. We should store this value somewhere and add the delta time to it before calling the method.

boolean looping: whether the animation loops or stops at the last frame.

In order to create an Animation instance we must supply the TextureRegion instances and the frame duration in seconds. As we're using the Texture Packer to create our image atlases, we can use our TextureAtlas instance to easily find all the frames the compose an animation just by calling textureAtlas.findRegions( "animation-name" ), which returns a list of AtlasRegion instances, which extend TextureRegion.

Note: we talked about the Texture Packer and image atlases in a previous post.

You can test and tune the frame duration value or come up with some formula, like: 2.5 / frameCount
That means the whole animation lasts 2.5 seconds.
Here you can read more about animations in libgdx if you want.

Scene 2D and animations

Scene 2D has no animation actor, but that's not a problem because we can just change our image actor's region based on the TextureRegion returned by the Animation class. Simply put, we can do something like this:

Creating the tilt animation

The Texture Packer created the following image atlas for us:

Notice that we just have the tilt animation to the left. Later we'll use a trick to inverse the image horizontaly, so the ship will be able to tilt to both sides. Let's define the new animation related attributes:

There is a small problem with this approach. Both the level screen and the start game screen have images for the ship, and as we use a convention to name our images, the retrieved regions contain the ship's image of the start game screen. This image is not a part of the tilt animation. We could just rename the images in order to avoid this conflict (and this is the best fix in my opinion), but there is a trick we can do. The Texture Packer stores the image's index when it's part of an animation. If the index is less than zero it's just an static image. The following code removes the undesired ship's image:

Based on the velocity vector we can tell if the ship is moving horizontaly.

We always increment the tiltAnimationStateTime variable with the given delta before requesting the next animation's frame to be drawn.

We flip the image horizontaly when needed. A positive width means the image is not inverted (it's being displayed as it is). A negative width means the image is inverted horizontaly.

If the ship is not moving horizontaly we reset the tiltAnimationStateTime variable and set the current frame to the first frame.

The following video shows the result:

Conclusion

The ship is now tilting to the side it's moving. We used some tricks to get this done, but the code is still readable. :)
This is the Subversion tag for this post, and this is the full source code for the Ship2D class.
Thanks for reading!

2012-05-28

Hi guys! I've been extremely busy with some parallel projects, but as I received some donations and
amazing feedbacks as well, I'll find some time to write more posts! In this one we'll talk about vectors, an element that allows us to represent positions, speeds, velocities, accelerations, directions, distances and so on.

Important changes

Updated the version of libgdx to the latest version available. All I had to do was to
download the latest build and replace the JARs and .so files in our projects.

Why should we use vectors?

Vectors are cool because they can represent some informations in a way that's easy to understand, handle and combine.
Basically they represent a direction or a point within a coordinate system, optionally with an associated scalar value.

So far we've dealt only with velocity, but we also want to add acceleration so that the ship's movement seems more real.
Using vectors we can easily calculate the final position of the ship after both forces were applied just by combining them!
If you want to study the vector concept in depth you can check out this Wikipedia page.

As you can see, they belong to the com.badlogic.gdx.math package, which is very useful. It provides implementations
of things like circles, planes, polygons, rectangles, spheres and so on. I suggest you take some time to study this
package in details. Maybe one day I'll write about it.

Using a position vector

As an example, we will change our game to use a vector to represent the ship's position.
Let's start by modifying the Ship2D class to include the following vector attribute:

private Vector2 position; // unitless

Sadly the (x,y) position coordinates of an actor are not wrapped into a Vector2 object.
That's why we're using a position vector. At specific moments we'll have to update the actor's position based on our position vector.
Now we could rewrite our Ship2D#moveShip method as follows (I omitted some code in favor of readability):

Using velocity and acceleration vectors

We're using vectors now, but the result was exactly the same as before!
When we add the acceleration vector we'll see all the magic happen.
First, let's understand the difference between speed, velocity and acceleration:

Speed is a scalar quantity that tells us how fast an object is moving; eg: 10m/s.

Velocity is a vector quantity that tells us how fast an object is moving and in what direction; eg: 10m/s east.

Acceleration is a vector quantity that tells us the rate of change of velocity; eg: 10m/s² south.

So what we need to do now is:

Calculate the acceleration based on the user input.

Modify the ship's velocity based on the calculated acceleration.

Update the ship's position based on the modified velocity.

And we should enforce some rules:

The maximum acceleration will be 8px/s². When using the keyboard, this maximum value is reached
immediately, but when using the device's accelerator it should be calculated.

The maximum speeds (horizontal and vertical) must be respected.

When reaching the boundaries, the ship's velocity should be zeroed, so that the ship stops flying
in the current direction.

Modifying the Ship2D#moveShip method

We need to set the maximum acceleration, just like we set the maximum speed:

Conclusion

We have implemented acceleration and the ship's behaviour seems more real!
Features like these are absolutely necessary if we want the player to be able to immerse in the game.
In the next post the ship will tilt to the side its moving, and then we'll move on to another actors!