
LibGDX core modules
LibGDX provides six core modules that allow you to access various parts of the system your application will run on. What makes these modules so great for you as a developer is that they provide you with a single Application Programming Interface (API) to achieve the same effect on more than just one platform. This is extremely powerful because you can now focus on your own application and do not have to bother with the specialties that each platform inevitably brings, including the nasty little bugs that might require tricky workarounds. This is all going to be transparently handled in a straightforward API, which is categorized into logic modules and is globally available anywhere in your code as every module is accessible as a static
field in the Gdx
class.
The application module
The application module can be accessed through Gdx.app
. It gives you access to the logging facility, a method to shutdown gracefully, persist data, query the Android API version, query the platform type, and query the memory usage.
LibGDX employs its own logging facility. You can choose a log level to filter what should be printed to the platform's console. The default log level is LOG_INFO
. You can use a settings file and/or change the log level dynamically at runtime using the following code:
Gdx.app.setLogLevel(Application.LOG_DEBUG);
The available log levels are as follows:
To write an info, debug, or error log to the console, use the following listings:
Gdx.app.log("MyDemoTag", "This is an info log."); Gdx.app.debug("MyDemoTag", "This is a debug log."); Gdx.app.error("MyDemoTag", "This is an error log.");
You can tell LibGDX to shut down the running application. The framework will then stop the execution in the correct order as soon as possible and completely deallocate any memory that is still in use, freeing both Java and the native heap. Use the following listing to initiate a graceful shutdown of your application:
Gdx.app.exit();
Note
You should always do a graceful shutdown when you want to terminate your application. Otherwise, you will risk creating memory leaks, which is a really bad thing. On mobile devices, memory leaks will probably have the biggest negative impact due to their limited resources. Note that in an Android device, it will call the pause()
and dispose()
functions sometime later and won't immediately finish the application.
If you want your data to persist after exit, you should use the Preferences
class. It is merely a dictionary or a hash map data type that stores multiple key-value pairs in a file. LibGDX will create a new preferences file on the fly if it does not exist. You can have several preference files using unique names in order to split up data into categories. To get access to a preference file, you need to request a Preferences
instance by its filename as follows:
Preferences prefs = Gdx.app.getPreferences("settings.prefs");
To write a (new) value, you have to choose a key under which the value should be stored. If this key already exists in a preferences file, it will be overwritten. Do not forget to call flush()
afterwards, as shown in the following code, to persist the data, or else all the changes will be lost:
prefs.putInteger("sound_volume", 100); // volume @ 100% prefs.flush();
To read back a certain value from the preferences file, you need to know the corresponding key. If this key does not exist, it will be set to the default value. You can optionally pass your own default value as the second argument (for example, in the following listing, 50
is the default sound volume):
int soundVolume = prefs.getInteger("sound_volume", 50);
On Android, you can query the Android API level that allows you to handle things differently for certain versions of the Android OS. Use the following listing to find out the version:
Gdx.app.getVersion();
You might want to write a platform-specific code where it is necessary to know the current platform type. The following example shows how it can be done:
switch (Gdx.app.getType()) { case Desktop: // Code for Desktop application break; case Android: // Code for Android application break; case WebGL: // Code for WebGL application break; case iOS: // Code for IOS application break; default: // Unhandled (new?) platform application break; }
You can query the system to find out its current memory footprint of your application. This might help you find excessive memory allocations that could lead to application crashes. The following functions return the amount of memory (in bytes) that is in use by the corresponding heap:
long memUsageJavaHeap = Gdx.app.getJavaHeap(); long memUsageNativeHeap = Gdx.app.getNativeHeap();
When our game is created, LibGDX creates a separate thread called the Main loop thread and OpenGL context is attached to it. The entire event processing or rendering happens within this thread and not in the UI thread. Hence to pass data to the rendering thread from another thread, we use Application.postRunnable()
. This will run the code in the Runnable
function in the rendering thread in the next frame, as shown in the following code:
Gdx.app.postRunnable(new Runnable() { @Override public void run() { //do something } });
The graphics module
The graphics module can be accessed either through Gdx.getGraphics()
or using the shortcut variable Gdx.graphics
.
Query LibGDX for the time span between the current and the last frame in seconds by calling Gdx.graphics.getDeltaTime()
.
The audio module
The audio module can be accessed either through Gdx.getAudio()
or using the shortcut variable Gdx.audio
.
To load sounds for playback, call Gdx.audio.newSound()
.
The supported file formats are WAV, MP3, and OGC. However, for the iOS version, OGG is not supported. There is an upper limit of 1 MB for the decoded audio data. Consider the sounds to be short effects such as bullets or explosions so that the size limitation is not really an issue.
The input module
The input module can be accessed either through Gdx.getInput()
or using the shortcut variable Gdx.input
.
In order to receive and handle the input properly, you should always implement the InputProcessor
interface and set it as the global handler for the input in LibGDX by calling Gdx.input.setInputProcessor()
.
Query the system for the last x or y coordinate in the screen coordinates, where the screen origin is at the top-left corner by calling either Gdx.input.getX()
or Gdx.input.getY()
. The different conditions are as follows:
- To find out whether the screen is touched either by a finger or by mouse, call
Gdx.input.isTouched()
- To find out whether the mouse button is pressed, call
Gdx.input.isButtonPressed()
- To find out whether the keyboard key is pressed, call
Gdx.input.isKeyPressed()
Query the accelerometer for its value on the x axis by calling Gdx.input.getAccelerometerX()
. Replace X
in the method's name with Y
or Z
to query the other two axes. Be aware that there will be no accelerometer present on a desktop, so LibGDX always returns 0
.
On Android, you can let the device vibrate by calling Gdx.input.vibrate()
. A running vibration can be canceled by calling Gdx.input.cancelVibrate()
.
You might want to catch Android's soft keys to add an extra handling code for them. If you want to catch the back button, call Gdx.input.setCatchBackKey(true)
, and if you want to catch the menu button, call Gdx.input.setCatchMenuKey(true)
.
On a desktop where you have a mouse pointer, you can tell LibGDX to catch it so that you get a permanent mouse input without having the mouse ever leave the application window. To catch the mouse cursor, call Gdx.input.setCursorCatched(true)
.
The files module
The files module can be accessed either through Gdx.getFiles()
or using the shortcut variable: Gdx.files
.
The network module
The network module can be accessed either through Gdx.getNet()
or using the shortcut variable: Gdx.net
.
You can make HTTP requests by calling Gdx.net.sendHttpRequest()
or cancel them by calling Gdx.net.cancelHttpRequest()
.