Tweening
The tween engine lets you animate any numeric value over time using easing functions. It is the cleanest
way to move sprites, fade objects, scale UI elements, or drive any other smooth transition without
hand-writing lerp logic in update. You configure a tween with a FlixelTweenSettings object and add
one or more goals via addGoal(getter, toValue, setter) — explicit getter and setter references, which
keeps tweens fully ahead-of-time compatible (no reflection).
- Java
- Kotlin
// Tween sprite.x from its current value to 400 over 1 second.
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setDuration(1.0f)
.addGoal(sprite::getX, 400f, sprite::setX));
// Fade out (alpha 1 -> 0) with easing, then destroy.
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setDuration(0.5f)
.setEase(FlixelEase::quadOut)
.addGoal(sprite::getAlpha, 0f, sprite::setAlpha)
.setOnComplete(t -> sprite.destroy()));
// Multiple goals in a single tween (all animate simultaneously).
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setDuration(1.0f)
.addGoal(sprite::getX, 400f, sprite::setX)
.addGoal(sprite::getAlpha, 0f, sprite::setAlpha));
// Keep the handle to cancel or pause a running tween.
FlixelTween tween = FlixelTween.tween(sprite, new FlixelTweenSettings()
.setDuration(2.0f)
.addGoal(sprite::getX, 400f, sprite::setX));
tween.cancel();
// Tween sprite.x from its current value to 400 over 1 second.
FlixelTween.tween(sprite, FlixelTweenSettings()
.setDuration(1.0f)
.addGoal(sprite::getX, 400f, sprite::setX))
// Fade out (alpha 1 -> 0) with easing, then destroy.
FlixelTween.tween(sprite, FlixelTweenSettings()
.setDuration(0.5f)
.setEase(FlixelEase::quadOut)
.addGoal(sprite::getAlpha, 0f, sprite::setAlpha)
.setOnComplete { sprite.destroy() })
// Multiple goals in a single tween (all animate simultaneously).
FlixelTween.tween(sprite, FlixelTweenSettings()
.setDuration(1.0f)
.addGoal(sprite::getX, 400f, sprite::setX)
.addGoal(sprite::getAlpha, 0f, sprite::setAlpha))
// Keep the handle to cancel or pause a running tween.
val tween = FlixelTween.tween(sprite, FlixelTweenSettings()
.setDuration(2.0f)
.addGoal(sprite::getX, 400f, sprite::setX))
tween.cancel()
Easing
Pass any easer function from FlixelEase as a method reference. The full easing library:
| Family | Easers |
|---|---|
| Linear | linear |
| Quadratic | quadIn, quadOut, quadInOut |
| Cubic | cubeIn, cubeOut, cubeInOut |
| Quartic | quartIn, quartOut, quartInOut |
| Quintic | quintIn, quintOut, quintInOut |
| Smooth step | smoothStepIn, smoothStepOut, smoothStepInOut |
| Smoother step | smootherStepIn, smootherStepOut, smootherStepInOut |
| Sine | sineIn, sineOut, sineInOut |
| Circular | circIn, circOut, circInOut |
| Exponential | expoIn, expoOut, expoInOut |
| Back (overshoot) | backIn, backOut, backInOut |
| Elastic | elasticIn, elasticOut, elasticInOut |
| Bounce | bounceIn, bounceOut, bounceInOut |
Common picks by feel:
| Easer | Feel |
|---|---|
FlixelEase::quadOut | Starts fast, decelerates — good for slide-in animations. |
FlixelEase::quadIn | Starts slow, accelerates — good for falling objects. |
FlixelEase::sineInOut | Very smooth, minimal pop. |
FlixelEase::backOut | Overshoots slightly, then snaps back — springy UI buttons. |
FlixelEase::elasticOut | Big overshoot, oscillates — playful pop-in effects. |
FlixelEase::bounceOut | Bounces at the end — cartoonish landings. |
FlixelEase::expoOut | Extremely fast start, very gradual stop. |
Callbacks
FlixelTweenSettings lets you attach callbacks for key tween events. Each callback receives the
running FlixelTween:
- Java
- Kotlin
new FlixelTweenSettings()
.setOnStart(t -> Flixel.info("Tween started"))
.setOnUpdate(t -> updateUI())
.setOnComplete(t -> nextAnimation());
FlixelTweenSettings()
.setOnStart { Flixel.info("Tween started") }
.setOnUpdate { updateUI() }
.setOnComplete { nextAnimation() }
If you need the interpolated value itself on every frame, use FlixelTween.num, whose update callback
is handed the current value:
- Java
- Kotlin
FlixelTween.num(0f, 1f, new FlixelTweenSettings().setDuration(1.0f), value -> updateUI(value));
FlixelTween.num(0f, 1f, FlixelTweenSettings().setDuration(1.0f)) { value -> updateUI(value) }
Looping and types
The FlixelTweenType controls what happens when a tween reaches the end:
| Type | Behavior |
|---|---|
ONESHOT | Runs once, then removes itself from the manager (default). |
PERSIST | Runs once, stays registered — resume it later with tween.restart(). |
BACKWARD | Plays once in reverse (from goal back to starting value). |
LOOPING | Restarts from the beginning immediately on finish. |
PINGPONG | Alternates direction on each iteration (forward, backward, forward...). |
- Java
- Kotlin
// ONESHOT: runs once and removes itself (the default, shown explicitly).
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setType(FlixelTweenType.ONESHOT)
.setDuration(0.5f)
.addGoal(sprite::getY, sprite.getY() - 20f, sprite::setY));
// PERSIST: runs once and stays registered so it can be restarted later.
FlixelTween doorOpen = FlixelTween.tween(door, new FlixelTweenSettings()
.setType(FlixelTweenType.PERSIST)
.setDuration(0.3f)
.addGoal(door::getX, door.getX() + 64f, door::setX));
// ... later, after the player re-enters:
doorOpen.restart();
// BACKWARD: plays once in reverse (animates from the goal back to the starting value).
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setType(FlixelTweenType.BACKWARD)
.setDuration(0.5f)
.addGoal(sprite::getAlpha, 0f, sprite::setAlpha));
// LOOPING: restarts from the beginning immediately on finish.
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setType(FlixelTweenType.LOOPING)
.setDuration(2.0f)
.addGoal(sprite::getAngle, 360f, sprite::setAngle));
// PINGPONG: alternates direction on each iteration (forward, backward, forward...).
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setType(FlixelTweenType.PINGPONG)
.setDuration(1.0f)
.addGoal(sprite::getX, 500f, sprite::setX));
// ONESHOT: runs once and removes itself (the default, shown explicitly).
FlixelTween.tween(sprite, FlixelTweenSettings()
.setType(FlixelTweenType.ONESHOT)
.setDuration(0.5f)
.addGoal(sprite::getY, sprite.getY() - 20f, sprite::setY))
// PERSIST: runs once and stays registered so it can be restarted later.
val doorOpen = FlixelTween.tween(door, FlixelTweenSettings()
.setType(FlixelTweenType.PERSIST)
.setDuration(0.3f)
.addGoal(door::getX, door.getX() + 64f, door::setX))
// ... later, after the player re-enters:
doorOpen.restart()
// BACKWARD: plays once in reverse (animates from the goal back to the starting value).
FlixelTween.tween(sprite, FlixelTweenSettings()
.setType(FlixelTweenType.BACKWARD)
.setDuration(0.5f)
.addGoal(sprite::getAlpha, 0f, sprite::setAlpha))
// LOOPING: restarts from the beginning immediately on finish.
FlixelTween.tween(sprite, FlixelTweenSettings()
.setType(FlixelTweenType.LOOPING)
.setDuration(2.0f)
.addGoal(sprite::getAngle, 360f, sprite::setAngle))
// PINGPONG: alternates direction on each iteration (forward, backward, forward...).
FlixelTween.tween(sprite, FlixelTweenSettings()
.setType(FlixelTweenType.PINGPONG)
.setDuration(1.0f)
.addGoal(sprite::getX, 500f, sprite::setX))
Timing control
setStartDelay waits before the tween begins. setLoopDelay inserts a pause between each
iteration of a looping tween. setFramerate snaps the tween's progress to discrete steps —
useful for animating integer-valued properties or achieving a retro look:
- Java
- Kotlin
FlixelTween.tween(sprite, new FlixelTweenSettings()
.setDuration(1.0f)
.setStartDelay(0.5f) // Wait 0.5s before starting.
.setLoopDelay(0.25f) // Pause 0.25s between loops.
.setFramerate(12f) // Snap to 12 steps per second.
.setType(FlixelTweenType.LOOPING)
.addGoal(sprite::getX, 400f, sprite::setX));
FlixelTween.tween(sprite, FlixelTweenSettings()
.setDuration(1.0f)
.setStartDelay(0.5f) // Wait 0.5s before starting.
.setLoopDelay(0.25f) // Pause 0.25s between loops.
.setFramerate(12f) // Snap to 12 steps per second.
.setType(FlixelTweenType.LOOPING)
.addGoal(sprite::getX, 400f, sprite::setX))
Color tweens
FlixelTween.color() interpolates a FlixelColorable object between two colors. FlixelSprite
implements FlixelColorable, so you can tween any sprite's tint:
- Java
- Kotlin
// Flash the sprite's tint from blue back to normal over 0.2 seconds.
FlixelTween.color(sprite, FlixelColor.BLUE, FlixelColor.WHITE,
new FlixelTweenSettings().setDuration(0.2f));
// Cycle the sky background between dawn and day colors.
FlixelTween.color(sky,
new FlixelColor(255, 180, 100, 1f),
new FlixelColor(135, 206, 235, 1f),
new FlixelTweenSettings()
.setType(FlixelTweenType.PINGPONG)
.setDuration(5.0f));
// Flash the sprite's tint from blue back to normal over 0.2 seconds.
FlixelTween.color(sprite, FlixelColor.BLUE, FlixelColor.WHITE,
FlixelTweenSettings().setDuration(0.2f))
// Cycle the sky background between dawn and day colors.
FlixelTween.color(sky,
new FlixelColor(255, 180, 100, 1f),
new FlixelColor(135, 206, 235, 1f),
FlixelTweenSettings()
.setType(FlixelTweenType.PINGPONG)
.setDuration(5.0f))
Angle tweens
FlixelTween.angle() rotates a FlixelAngleable to a target angle, automatically taking the
shortest arc. Pass a from angle to override the starting value:
- Java
- Kotlin
// Spin the sprite to 90 degrees over 0.4 seconds.
FlixelTween.angle(sprite, 90f, new FlixelTweenSettings().setDuration(0.4f));
// Spin from 0 to 360 (full rotation) looping forever.
FlixelTween.angle(sprite, 0f, 360f, new FlixelTweenSettings()
.setType(FlixelTweenType.LOOPING)
.setDuration(2.0f));
// Spin the sprite to 90 degrees over 0.4 seconds.
FlixelTween.angle(sprite, 90f, FlixelTweenSettings().setDuration(0.4f))
// Spin from 0 to 360 (full rotation) looping forever.
FlixelTween.angle(sprite, 0f, 360f, FlixelTweenSettings()
.setType(FlixelTweenType.LOOPING)
.setDuration(2.0f))
Motion tweens
Motion tweens move a FlixelPositional along a path without manually setting x and y goals.
Linear motion
Move directly from one point to another:
- Java
- Kotlin
// Move sprite from (100, 100) to (400, 300) over 1.5 seconds.
FlixelTween.linearMotion(sprite, 100f, 100f, 400f, 300f, 1.5f, true,
new FlixelTweenSettings().setEase(FlixelEase::quadInOut));
// Move sprite from (100, 100) to (400, 300) over 1.5 seconds.
FlixelTween.linearMotion(sprite, 100f, 100f, 400f, 300f, 1.5f, true,
FlixelTweenSettings().setEase(FlixelEase::quadInOut))
Circular motion
Orbit a center point. Pass angleDeg for the starting angle (0 = right, 90 = up in screen space):
- Java
- Kotlin
// Orbit the center of the screen clockwise, one revolution every 3 seconds.
FlixelTween.circularMotion(sprite,
640f, 360f, // Center point.
120f, // Orbit radius.
0f, // Starting angle (degrees).
true, // Clockwise.
3.0f, true, // Duration 3 seconds.
new FlixelTweenSettings().setType(FlixelTweenType.LOOPING));
// Orbit the center of the screen clockwise, one revolution every 3 seconds.
FlixelTween.circularMotion(sprite,
640f, 360f, // Center point.
120f, // Orbit radius.
0f, // Starting angle (degrees).
true, // Clockwise.
3.0f, true, // Duration 3 seconds.
FlixelTweenSettings().setType(FlixelTweenType.LOOPING))
Quadratic Bezier motion
Curve through a control point for smooth arced movement:
- Java
- Kotlin
// Arc from (100, 400) through control point (400, 50) to (700, 400) over 1 second.
// The control point pulls the path toward it without the object ever reaching it.
FlixelTween.quadMotion(sprite,
100f, 400f, // Start.
400f, 50f, // Control point (the arc peak).
700f, 400f, // End.
1.0f, true, // Duration.
new FlixelTweenSettings().setEase(FlixelEase::sineInOut));
// Arc from (100, 400) through control point (400, 50) to (700, 400) over 1 second.
// The control point pulls the path toward it without the object ever reaching it.
FlixelTween.quadMotion(sprite,
100f, 400f, // Start.
400f, 50f, // Control point (the arc peak).
700f, 400f, // End.
1.0f, true, // Duration.
FlixelTweenSettings().setEase(FlixelEase::sineInOut))
Cubic Bezier motion
cubicMotion takes four explicit points — p0 (start), p1 and p2 (the two control points), and p3
(end). The two control points give you independent control over the entry and exit tangents of the
curve, allowing sharper turns and S-curves that a single control point cannot produce:
- Java
- Kotlin
// S-curve: exit right from (100, 400), curve up, then arrive from the left at (700, 100).
FlixelTween.cubicMotion(sprite,
100f, 400f, // p0: start.
400f, 400f, // p1: first control point (pulls exit tangent right).
300f, 100f, // p2: second control point (pulls entry tangent left).
700f, 100f, // p3: end.
1.5f, true, // Duration 1.5 seconds.
new FlixelTweenSettings().setEase(FlixelEase::sineInOut));
// S-curve: exit right from (100, 400), curve up, then arrive from the left at (700, 100).
FlixelTween.cubicMotion(sprite,
100f, 400f, // p0: start.
400f, 400f, // p1: first control point (pulls exit tangent right).
300f, 100f, // p2: second control point (pulls entry tangent left).
700f, 100f, // p3: end.
1.5f, true, // Duration 1.5 seconds.
FlixelTweenSettings().setEase(FlixelEase::sineInOut))
Piecewise-linear path
Pass a flat array of x, y pairs to move through multiple waypoints in sequence:
- Java
- Kotlin
// Patrol a three-point path over 4 seconds.
FlixelTween.linearPath(guard, 4.0f, true,
new FlixelTweenSettings().setType(FlixelTweenType.PINGPONG),
100f, 200f, // Waypoint 1.
400f, 200f, // Waypoint 2.
400f, 500f); // Waypoint 3.
// Patrol a three-point path over 4 seconds.
FlixelTween.linearPath(guard, 4.0f, true,
FlixelTweenSettings().setType(FlixelTweenType.PINGPONG),
100f, 200f, // Waypoint 1.
400f, 200f, // Waypoint 2.
400f, 500f) // Waypoint 3.
Quadratic Bezier path
quadPath connects multiple quadratic Bézier segments into one continuous curved path. The point
layout is start, control, end, control, end, ... — the first pair is the start point, then each
subsequent segment adds a control point and an end point. The minimum is three points (six floats):
- Java
- Kotlin
// Two-segment curved path: start at (100, 300), arc through (300, 100) to (500, 300),
// then arc through (700, 500) to (900, 300).
FlixelTween.quadPath(sprite, 2.0f, true,
new FlixelTweenSettings(),
100f, 300f, // Start.
300f, 100f, // Control point for segment 1.
500f, 300f, // End of segment 1 (start of segment 2).
700f, 500f, // Control point for segment 2.
900f, 300f); // End of segment 2.
// Two-segment curved path: start at (100, 300), arc through (300, 100) to (500, 300),
// then arc through (700, 500) to (900, 300).
FlixelTween.quadPath(sprite, 2.0f, true,
FlixelTweenSettings(),
100f, 300f, // Start.
300f, 100f, // Control point for segment 1.
500f, 300f, // End of segment 1 (start of segment 2).
700f, 500f, // Control point for segment 2.
900f, 300f) // End of segment 2.
Flicker and shake tweens
FlixelTween.flicker() toggles a sprite's visibility on and off at a given period. It is the
standard technique for brief invincibility frames after a hit:
- Java
- Kotlin
// Flicker the player for 1.5 seconds (default period and ratio).
FlixelTween.flicker(player, new FlixelTweenSettings().setDuration(1.5f));
// Flicker with a custom period (0.08s on/off cycle) and 50% duty cycle.
FlixelTween.flicker(player, 0.08f, 0.5f, true,
new FlixelTweenSettings().setDuration(1.5f), null);
// Flicker the player for 1.5 seconds (default period and ratio).
FlixelTween.flicker(player, FlixelTweenSettings().setDuration(1.5f))
// Flicker with a custom period (0.08s on/off cycle) and 50% duty cycle.
FlixelTween.flicker(player, 0.08f, 0.5f, true,
FlixelTweenSettings().setDuration(1.5f), null)
FlixelTween.shake() displaces a FlixelShakeable object (such as a sprite or group) by a random
offset on each frame, on the chosen axes:
- Java
- Kotlin
// Shake the player sprite with 4-pixel intensity for 0.3 seconds on both axes.
FlixelTween.shake(player, FlixelAxes.XY, 4f,
new FlixelTweenSettings().setDuration(0.3f));
// Shake the player sprite with 4-pixel intensity for 0.3 seconds on both axes.
FlixelTween.shake(player, FlixelAxes.XY, 4f,
FlixelTweenSettings().setDuration(0.3f))
Pause and resume
Call pause() and resume() on a tween handle to freeze and unfreeze it mid-animation:
- Java
- Kotlin
FlixelTween doorTween = FlixelTween.tween(door, new FlixelTweenSettings()
.setDuration(0.5f)
.addGoal(door::getX, 200f, door::setX));
// Pause it when a cutscene starts.
doorTween.pause();
// Resume when the cutscene ends.
doorTween.resume();
val doorTween = FlixelTween.tween(door, FlixelTweenSettings()
.setDuration(0.5f)
.addGoal(door::getX, 200f, door::setX))
// Pause it when a cutscene starts.
doorTween.pause()
// Resume when the cutscene ends.
doorTween.resume()
Canceling tweens in bulk
FlixelTween.cancelTweensOf(object) cancels every active tween targeting a given object. Use it
when destroying an object that may have multiple tweens running:
- Java
- Kotlin
// Cancel all tweens on this enemy before removing it from the scene.
FlixelTween.cancelTweensOf(enemy);
enemy.destroy();
// Cancel all tweens on this enemy before removing it from the scene.
FlixelTween.cancelTweensOf(enemy)
enemy.destroy()
Because each goal uses explicit getter and setter references, any float property on any object is
tweenable — including properties on your own custom classes — with no reflection and no framework coupling.