Skip to main content

Core Concepts

This page walks through the 6 essential classes and systems that form the foundation of every FlixelGDX game. Each section includes practical code examples in both Java and Kotlin.


1. Flixel — the global manager system

Flixel is the static gateway to every major subsystem in the framework. Think of it as the equivalent of FlxG in HaxeFlixel — one central place that holds references to the active state, cameras, input, audio, assets, the debugger, and more.

Common access points:

Field / methodWhat it gives you
Flixel.soundAudio manager (FlixelAudioManager)
Flixel.assetsAsset manager (FlixelAssetManager)
Flixel.debugDebug manager (FlixelDebugManager)
Flixel.watchWatch panel manager (FlixelDebugWatchManager)
Flixel.keysKeyboard input
Flixel.mouseMouse input
Flixel.gamepadsGamepad(s) input
Flixel.switchState(state)Transition to a new state
Flixel.camerasThe live list of all active cameras
Flixel.cameras.first()The main (first) camera

2. FlixelGame — the heart of every game

FlixelGame is the root and core part of your game. You extend it once, configure your window title, screen size, and initial state, and the framework handles the rest: the game loop, input routing, camera management, the debug overlay, and the lifecycle of your states.

public class MyGame extends FlixelGame {

public MyGame() {
super(
"My Game", // Window title.
1280, 720, // World dimensions (virtual resolution).
new PlayState() // Initial state.
);
}
}

Then use a simple, dedicated platform launcher:

public static void main(String[] args) {
FlixelLwjgl3Launcher.launch(new MyGame());
}
World size stays the same regardless of window size

The world dimensions define the virtual resolution your game logic works in. When your game launches, the world size will match your window's starting size, too. In the example above, when the initial size is set to be 1280x720, your game's window will start at 1280x720 pixels, and your game's world view will stay at that size regardless when your window size changes.


3. FlixelState — organizing different parts of your game

FlixelState is the container for everything in a single "screen" of your game — a menu, a level, or a cutscene. You add sprites, groups, and other objects to a state, and the framework calls update(float) and draw(Batch) on all of them every frame. Override create() to build the screen and update(float) for per-frame logic.

public class PlayState extends FlixelState {

private FlixelSprite player;

@Override
public void create() {
super.create();
player = new FlixelSprite(100, 100);
player.loadGraphic("player.png"); // Assuming it's from the assets folder!
add(player);
}

@Override
public void update(float elapsed) {
super.update(elapsed);
// Game logic here!
}
}

Switch between states with Flixel.switchState(new YourState()); (or Flixel.switchState(YourState()) for Kotlin). The old state is destroyed automatically. FlixelSubState lets you overlay a temporary state (pause menu, inventory screen) on top of the current one without destroying it.


4. FlixelSprite — visual objects in your game

FlixelSprite is the workhorse of any FlixelGDX game. It represents a visual object in the world with position, size, texture, animation, velocity, and a hitbox. Most visible game objects extend FlixelSprite or hold one as a field.

FlixelSprite sprite = new FlixelSprite(x, y);

// Load a static image (this is assumed it's stored in the assets folder!).
sprite.loadGraphic("tile.png");

// Or make a solid-color rectangle (useful for prototyping).
sprite.makeGraphic(32, 32, FlixelColor.RED);

// Move with velocity on the X axis (pixels per second).
sprite.setVelocityX(200f);

// Scale, rotate, flip.
sprite.setScale(2f); // Scales the sprite twice as large both horizontally and vertically.
sprite.setAngle(45f);
sprite.flip(true, false); // Flip horizontally.

Sprite animation (frame-based clips, Sparrow atlases) lives in FlixelAnimationController, which is allocated on demand via sprite.ensureAnimation() to keep memory usage low for large sprite counts.


5. FlixelText — text objects and custom fonts

FlixelText renders a string inside the game world as a sprite. It extends FlixelSprite, so it shares the same positioning, scaling, and lifecycle, and you can add it to any state or group. The constructor takes the position, a field width, and the text.

FlixelText label = new FlixelText(10, 10, 200, "Hello, world!");
label.setTextSize(24);
label.setColor(FlixelColor.WHITE);
add(label);

// Update the text any time.
label.setText("Score: " + score);
Use FlixelString for optimization!

In the JVM, there's a very subtle and sneaky thing that can add pressure to the garbage collector and ruin your consistent framerate: string concatenation. When you use the example above, "Score: " + score / "Score: $score" seem pretty harmless on the surface, but it secretly creates new String objects. When inside an update loop, this can be fatal for a game's framerate.

You can avoid this problem using the framework's built-in utility FlixelString. Not only does it solve the per-frame allocation problem, but it also doesn't create additional String objects when primitives (like the int score below) are concatenated to a FlixelString!

Example usage:

// 16 is the initial capacity (in characters) of the backing CharArray.
// Sizing it up front matters: if the text ever grows past the current capacity,
// the FlixelString has to allocate a bigger array and copy everything over. Pick a
// number a little larger than your longest expected string and that copy never happens.
FlixelString labelText = new FlixelString(16);
FlixelText label = new FlixelText(10, 10, 200);

// Reuse the same FlixelString every frame. set(...) replaces the contents (no need to
// clear() first), and each concat(...) appends without allocating a new String.
label.setText(labelText
.set("Score: ")
.concat(score));

Custom fonts

Load and register a TrueType or OpenType font file on FlixelFontRegistry, then apply it on a FlixelText object:

final String MY_FONT = "my_font_id";
FlixelFontRegistry.register(MY_FONT, Gdx.files.internal("path/to/my/font.ttf")); // Assumes it's from the assets folder!

FlixelText label = new FlixelText(10, 10, 200);
label.setFont(MY_FONT); // Applies it from your ID!
label.setTextSize(16);

FlixelGDX uses libGDX's FreeType extension under the hood, so any .ttf or .otf file is supported. The font is rasterized at the exact pixel size you request, which keeps text crisp at any resolution.


6. FlixelGroup / FlixelBasicGroup / FlixelSpriteGroup — organizing objects

Groups are containers that hold objects, making it easy to organize your game. A FlixelSpriteGroup (or your own FlixelBasicGroup subclass) is itself a FlixelBasic, so you can add it straight to a state and pass it to Flixel.collide(group, other) to check every member at once.

ClassHoldsNotes
FlixelGroup<T>Any type TA plain container for organizing objects. It is not part of the scene graph: it does not update, draw, or collide on its own. Its constructor needs an array factory (e.g. Actor[]::new) because Java cannot create generic arrays.
FlixelBasicGroup<T>Any IFlixelBasicAn abstract base. Extend it to build a custom group whose members are updated, drawn, and collided automatically. (FlixelState itself is a FlixelBasicGroup.)
FlixelSpriteGroupFlixelSprite (and subclasses)The ready-to-use, concrete group most games reach for. Add it to a state, collide it, and it propagates position, scale, alpha, tint, and rotation to its members.
// FlixelGroup is a plain container. It needs an array factory because Java cannot
// allocate generic arrays, and it does not update, draw, or collide on its own.
FlixelGroup<Actor> actors = new FlixelGroup<>(Actor[]::new);
actors.add(new MyActorClass());

// FlixelSpriteGroup is the ready-to-use group: it updates, draws, and collides.
FlixelSpriteGroup enemies = new FlixelSpriteGroup();
for (int i = 0; i < 10; i++) {
EnemySprite e = new EnemySprite();
e.loadGraphic("enemy.png");
enemies.add(e);
}
add(enemies);

// Collide the player against every member in one call.
Flixel.collide(player, enemies);

FlixelSpriteGroup and advanced rotation

FlixelSpriteGroup propagates its own position, scale, alpha, color tint, and rotation to all member sprites. Its RotationMode enum (nested in FlixelSpriteGroup) supports three modes:

  • INDIVIDUAL (default) — the rotation delta is applied to each sprite's own rotation; positions are unchanged.
  • ORBIT — sprites orbit the group origin as a rigid body; both position and sprite rotation update.
  • WHEEL — sprites are arranged radially at a fixed radius from the group origin; useful for circular formations.
FlixelSpriteGroup formation = new FlixelSpriteGroup();
formation.setX(400);
formation.setY(300);
formation.changeAngle(90f);
formation.setRotationMode(FlixelSpriteGroup.RotationMode.ORBIT); // Rotate all sprites around the group's origin. (400, 300).