Skip to main content

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).

// 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();

Easing

Pass any easer function from FlixelEase as a method reference. The full easing library:

FamilyEasers
Linearlinear
QuadraticquadIn, quadOut, quadInOut
CubiccubeIn, cubeOut, cubeInOut
QuarticquartIn, quartOut, quartInOut
QuinticquintIn, quintOut, quintInOut
Smooth stepsmoothStepIn, smoothStepOut, smoothStepInOut
Smoother stepsmootherStepIn, smootherStepOut, smootherStepInOut
SinesineIn, sineOut, sineInOut
CircularcircIn, circOut, circInOut
ExponentialexpoIn, expoOut, expoInOut
Back (overshoot)backIn, backOut, backInOut
ElasticelasticIn, elasticOut, elasticInOut
BouncebounceIn, bounceOut, bounceInOut

Common picks by feel:

EaserFeel
FlixelEase::quadOutStarts fast, decelerates — good for slide-in animations.
FlixelEase::quadInStarts slow, accelerates — good for falling objects.
FlixelEase::sineInOutVery smooth, minimal pop.
FlixelEase::backOutOvershoots slightly, then snaps back — springy UI buttons.
FlixelEase::elasticOutBig overshoot, oscillates — playful pop-in effects.
FlixelEase::bounceOutBounces at the end — cartoonish landings.
FlixelEase::expoOutExtremely fast start, very gradual stop.

Callbacks

FlixelTweenSettings lets you attach callbacks for key tween events. Each callback receives the running FlixelTween:

new FlixelTweenSettings()
.setOnStart(t -> Flixel.info("Tween started"))
.setOnUpdate(t -> updateUI())
.setOnComplete(t -> nextAnimation());

If you need the interpolated value itself on every frame, use FlixelTween.num, whose update callback is handed the current value:

FlixelTween.num(0f, 1f, new FlixelTweenSettings().setDuration(1.0f), value -> updateUI(value));

Looping and types

The FlixelTweenType controls what happens when a tween reaches the end:

TypeBehavior
ONESHOTRuns once, then removes itself from the manager (default).
PERSISTRuns once, stays registered — resume it later with tween.restart().
BACKWARDPlays once in reverse (from goal back to starting value).
LOOPINGRestarts from the beginning immediately on finish.
PINGPONGAlternates direction on each iteration (forward, backward, forward...).
// 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));

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:

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));

Color tweens

FlixelTween.color() interpolates a FlixelColorable object between two colors. FlixelSprite implements FlixelColorable, so you can tween any sprite's tint:

// 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));

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:

// 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));

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:

// 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));

Circular motion

Orbit a center point. Pass angleDeg for the starting angle (0 = right, 90 = up in screen space):

// 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));

Quadratic Bezier motion

Curve through a control point for smooth arced movement:

// 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));

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:

// 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));

Piecewise-linear path

Pass a flat array of x, y pairs to move through multiple waypoints in sequence:

// 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.

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):

// 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.

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:

// 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);

FlixelTween.shake() displaces a FlixelShakeable object (such as a sprite or group) by a random offset on each frame, on the chosen axes:

// 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));

Pause and resume

Call pause() and resume() on a tween handle to freeze and unfreeze it mid-animation:

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();

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:

// 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.