Skip to main content

Cameras

Every FlixelGDX game has at least one FlixelCamera. It maps the virtual world to the physical screen and can follow sprites, zoom, scroll, shake, and flash. Adding more cameras enables split-screen, picture-in-picture, and separate UI layers.

// The main camera is always Flixel.cameras.first().
FlixelCamera cam = Flixel.cameras.first();
cam.follow(player, FlixelCamera.FollowStyle.TOPDOWN);
cam.setZoom(1.5f);
cam.angle += 30f;

Follow behavior

follow() continuously moves the camera to keep a target sprite (or any FlixelPositional) in frame. The FollowStyle preset controls what shape of dead zone is used — the region the target can move inside without the camera shifting.

StyleDead zone shapeBest for
LOCKONNone (instant tracking)Fixed chase cameras
PLATFORMERWide horizontal, narrow verticalSide-scrolling platformers
TOPDOWNCentered squareTop-down games with moderate speed
TOPDOWN_TIGHTSmall centered squareFast top-down games
SCREEN_BY_SCREENWhole screenZelda-style room transitions
NO_DEAD_ZONENo automatic trackingManual scroll control

Smooth follow

Pass a lerp value (0 = frozen, 1 = instant) to the three-argument overload for a drifting camera. followLeadX and followLeadY shift the camera ahead of the target in the direction of movement:

FlixelCamera cam = Flixel.cameras.first();

// 0.08 lerp gives a smooth, slightly lagging camera.
cam.follow(player, FlixelCamera.FollowStyle.PLATFORMER, 0.08f);

// Peek 20 pixels ahead of the player horizontally.
cam.followLeadX = 20f;

Snapping and focus

focusOn(worldX, worldY) instantly centers the camera on a world coordinate without changing the follow target. snapToTarget() cancels the current lerp and jumps directly to the follow target, useful for resetting the camera after a teleport:

// Center the camera on a boss spawn point immediately.
cam.focusOn(bossX, bossY);

// After a teleport, skip the lerp slide-in.
cam.snapToTarget();

Scroll bounds

Use setScrollBoundsRect to constrain the camera so it never scrolls past the edges of your level. Pass the level's top-left origin and its full width and height:

// Constrain to a 3200x1800 level starting at (0, 0).
// The camera will not show anything outside this rectangle.
cam.setScrollBoundsRect(0f, 0f, 3200f, 1800f);

If you need separate per-axis control you can set cam.minScrollX, cam.maxScrollX, cam.minScrollY, and cam.maxScrollY directly, or use the four-argument setScrollBounds(minX, maxX, minY, maxY).


Screen effects

flash, fade, and shake are the three built-in camera effects. Every overload accepts an optional completion Runnable and a force flag — force = true interrupts an already-running effect of the same type; force = false (the default) lets the current one finish first.

FlixelCamera cam = Flixel.cameras.first();

// Flash white for 0.3 seconds, then log a message.
cam.flash(FlixelColor.WHITE, 0.3f, () -> Flixel.info("Flash done"), false);

// Fade in from black over 0.8 seconds (fadeIn = true).
cam.fade(FlixelColor.BLACK, 0.8f, true, null, false);

// Fade out to black over 1.0 seconds.
cam.fade(FlixelColor.BLACK, 1.0f, false, () -> Flixel.switchState(new MenuState()), false);

// Shake intensity 2%, both axes, 0.5 seconds.
cam.shake(0.02f, 0.5f);

// Stop all effects immediately.
cam.stopFX();

You can also stop effects individually with stopFlash(), stopFade(), and stopShake(), and query whether each is still running with isFlashActive(), isFadeActive(), and isShakeActive().

Fade in on level start

Call cam.fade(FlixelColor.BLACK, 0.5f, true, null, false) at the top of your state's create() to fade in from black every time the level loads. fadeIn = true reverses the overlay direction so it starts opaque and clears to transparent.


Background color

Each camera clears to a background color before drawing. Setting it per-camera is useful when you have a separate UI camera that should be transparent:

// Change the main camera's background to a deep blue sky.
Flixel.cameras.first().setBgColor(new FlixelColor(30, 30, 80, 1.0f));

// Make a UI camera background fully transparent.
uiCamera.useBgAlphaBlending = true;
uiCamera.setBgColor(new FlixelColor(0f, 0f, 0f, 0f));

Custom viewport

Pass a custom libGDX Camera or Viewport to the FlixelCamera constructor to control how the virtual world is mapped to the screen. For example, a ScreenViewport uses actual pixel dimensions:

Viewport vp = new ScreenViewport();
FlixelCamera uiCamera = new FlixelCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), vp);
Flixel.cameras.add(uiCamera);

Split-screen

Add multiple cameras, switch each to normalized region mode, and set their screen rectangles with setScreenRegionNormalized:

FlixelCamera cam1 = new FlixelCamera(640, 720);
FlixelCamera cam2 = new FlixelCamera(640, 720);
cam1.setRegionMode(FlixelCamera.RegionMode.NORMALIZED_RECT);
cam2.setRegionMode(FlixelCamera.RegionMode.NORMALIZED_RECT);
cam1.setScreenRegionNormalized(0f, 0f, 0.5f, 1.0f); // left half
cam2.setScreenRegionNormalized(0.5f, 0f, 0.5f, 1.0f); // right half
cam1.follow(player1);
cam2.follow(player2);
Flixel.cameras.clear(); // Clear the list so you can use only your explicit cameras!
Flixel.cameras.add(cam1);
Flixel.cameras.add(cam2);

The RegionMode enum controls how region coordinates are interpreted:

ModeCoordinate space
NORMALIZED_RECT0.0 to 1.0, top-left origin
PIXEL_TOP_LEFTPixels, top-left origin (HaxeFlixel-style)
PIXEL_BOTTOM_LEFTPixels, bottom-left origin (libGDX-style)
PIXEL_CENTEREDPixels, center-anchored

Per-sprite camera assignment

By default every sprite renders on all cameras. Assign a sprite to specific cameras through its public cameras array to restrict it — useful for HUD elements that should only appear on a dedicated UI camera:

// This HUD sprite only renders on the UI camera, not on the world camera.
hudSprite.cameras = new FlixelCamera[]{ uiCamera };

Post-processing shaders

Attach a FlixelShader to a camera to apply a full-screen GLSL shader to everything that camera renders. The shader runs after the scene is composited into the camera's framebuffer:

FlixelCamera cam = Flixel.cameras.first();

// Load and attach a shader from GLSL source files.
FlixelShader crtShader = new FlixelShader(
Gdx.files.internal("shaders/crt.vert"),
Gdx.files.internal("shaders/crt.frag")
);
cam.setShader(crtShader);

// Remove the shader later.
cam.setShader(null);

Each camera maintains its own offscreen FrameBuffer. When a shader is set, the camera renders the scene into that buffer first, then applies the shader when blitting to the screen. Cameras without shaders skip the framebuffer entirely and render directly.