Basic ApplicationListener
implementations and general libGDX utilities.
While libGDX offers some basic ApplicationListener
implementations including ApplicationAdapter
and Game
, both are
pretty bare-bones. They do not handle screen clearing or manage views list, both of which often have to be set up
manually in libGDX applications. This module aims to provide a simple base for your custom ApplicationListener
implementations.
KtxApplicationAdapter
is an interface that extendsApplicationListener
. Provides no-op implementations of all methods, without being an abstract class likecom.badlogic.gdx.ApplicationAdapter
, which makes it more flexible.KtxGame
is a bit more opinionatedGame
equivalent that not only delegates all game events to the currentScreen
instance, but also ensures non-nullability of screens, manages screen clearing, and maintains screens collection, which allows switching screens while knowing only their concrete class.KtxScreen
is an interface extendingScreen
that provides no-op method implementations, making all methods optional to override.
KtxInputAdapter
is an interface extendingInputProcessor
. Provides no-op implementations of all methods, without being a class likecom.badlogic.gdx.InputAdapter
.
clearScreen
is an inlined utility function that hides the OpenGL calls, allowing to clear the screen with a chosen color.emptyScreen
provides no-op implementations ofScreen
.gdxError
throws aGdxRuntimeException
with an optional message and cause.
Platform
is an object that exposes various utilities for platform-specific code.Platform.currentPlatform
returns currentApplicationType
or throwsGdxRuntimeException
if unable to determine.Platform.version
returns the current version of the platform (e.g., Android API version, iOS major OS version).- Convenient checks that allow to determine current platform:
Platform.isAndroid
checks if the current platform is Android.Platform.isDesktop
checks if the current platform is desktop with graphical application.Platform.isHeadless
checks if the current platform is desktop without graphical application.Platform.isiOS
checks if the current platform is iOS.Platform.isMobile
checks if the current platform is Android or iOS.Platform.isWeb
checks if the current platform is HTML/WebGL.
- Inlined methods that allow to execute code on specific platforms:
Platform.runOnAndroid
executes an action if the current platform is Android. Returns action result or null.Platform.runOnDesktop
executes an action if the current platform is desktop. Returns action result or null.Platform.runOnHeadless
executes an action if the current platform is headless desktop. Returns action result or null.Platform.runOniOS
executes an action if the current platform is iOS. Returns action result or null.Platform.runOnMobile
executes an action if the current platform is Android or iOS. Returns action result or null.Platform.runOnWeb
executes an action if the current platform is HTML/WebGL. Returns action result or null.
- Inlined
runOnVersion
executes an action if the current platform version is within minimum and maximum values.
profile
inlined function allows measuring performance of the chosen operation with libGDXPerformanceCounter
.PerformanceCounter.profile
inlined extension method eases direct usage of thePerformanceCounter
class.PerformanceCounter.prettyPrint
extension method allows to quickly log basic performance metrics.
Implementing KtxApplicationAdapter
:
import ktx.app.KtxApplicationAdapter
class MyApplicationListener : KtxApplicationAdapter {
// Implementation of all ApplicationListener methods is optional. Override the ones you need.
override fun create() {
// Load the assets...
}
override fun render() {
// ...and render your game.
}
}
Implementing KtxGame
with one screen that displays text with Batch
utilities from ktx-graphics
:
import com.badlogic.gdx.Screen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.BitmapFont
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import ktx.app.KtxGame
import ktx.app.KtxScreen
import ktx.graphics.use
class ExampleScreen : KtxScreen {
// Notice no `lateinit var` - ExampleScreen has no create()
// method and is constructed after libGDX is fully initiated
// in ExampleGame.create method.
val font = BitmapFont()
val batch = SpriteBatch().apply {
color = Color.WHITE
}
override fun render(delta: Float) {
batch.use {
font.draw(it, "Hello Kotlin!", 100f, 100f)
}
}
override fun dispose() {
// Will be automatically disposed of by the game instance.
font.dispose()
batch.dispose()
}
}
/** ApplicationListener implementation. */
class ExampleGame : KtxGame<Screen>() {
override fun create() {
// Registering ExampleScreen in the game object: it will be
// accessible through ExampleScreen class:
addScreen(ExampleScreen())
// Changing current screen to the registered instance of the
// ExampleScreen class:
setScreen<ExampleScreen>()
}
}
Implementing KtxInputAdapter
:
import ktx.app.KtxInputAdapter
class MyInputListener : KtxInputAdapter {
// Implementation of all ApplicationListener methods is optional. Handle the events you plan on supporting.
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
// Handle mouse click...
return true
}
}
Obtaining the current platform type:
import com.badlogic.gdx.Application.ApplicationType
import ktx.app.Platform
fun getCurrentPlatform(): ApplicationType {
return Platform.currentPlatform
}
Verifying the current platform:
import ktx.app.Platform
fun checkPlatform() {
if (Platform.isDesktop || Platform.isHeadless) {
println("Will print only on desktop platforms!")
}
}
Executing platform-specific code:
import ktx.app.Platform
fun runOnPlatform() {
Platform.runOnMobile {
println("Will print only on mobile platforms!")
}
}
Executing platform-specific code with a return type:
import ktx.app.Platform
fun getForPlatform(): String {
return Platform.runOnAndroid { "Android" } ?: "Not Android"
}
Executing code starting from a specific API version:
import com.badlogic.gdx.Application.ApplicationType
import ktx.app.Platform
fun executeOnSpecificVersion() {
Platform.runOnVersion(minVersion = 8, platform = ApplicationType.iOS) {
println("Will run only on iOS devices starting from 8 OS version.")
}
}
Executing code on a specific API version range:
import com.badlogic.gdx.Application.ApplicationType
import ktx.app.Platform
fun executeOnSpecificVersion() {
Platform.runOnVersion(minVersion = 20, maxVersion = 25, platform = ApplicationType.Android) {
println("Will run only on specific Android devices.")
}
}
Profiling an operation:
import ktx.app.profile
fun profileThreadSleep() {
profile(name = "Thread.sleep", repeats = 10) {
// Will be repeated 10 times to measure performance:
Thread.sleep(10L)
}
}
Profiling an operation with an existing PerformanceCounter
:
import com.badlogic.gdx.utils.PerformanceCounter
import ktx.app.prettyPrint
import ktx.app.profile
fun profileThreadSleep() {
// Window size passed to the constructor as the second argument
// will be the default amount of repetitions during profiling:
val profiler = PerformanceCounter("Thread.sleep", 10)
profiler.profile {
// Will be repeated 10 times to measure performance:
Thread.sleep(10L)
}
// You can also print the report manually
// with a custom number format:
profiler.prettyPrint(decimalFormat = "%.4f s")
}
There are some general purpose libGDX utility libraries out there, but most lack first-class Kotlin support.
- Kiwi is a general purpose Guava-inspired libGDX Java utilities
library with some classes similar to
ktx-app
. - LML allows building
Scene2D
views using HTML-like syntax. It also features a customApplicationListener
implementation, which helps with managingScene2D
screens. - Autumn MVC is a Spring inspired
model-view-controller framework built on top of libGDX. It features its own
ApplicationListener
implementation, which initiates and handles annotated view instances.