Upgrade Guide 4.0.0
4.4.0
Breaking changes in 4.4.0 are limited to usage with OpenFL 8. OpenFL 3.6.1 (Legacy or Next) is still fully supported. The breaking changes when upgrading to OpenFL 8.0.0 and Lime 6.3.0 are as follows:
- There is no support for blend modes (
FlxSprite.blend). This is becausedrawQuads()(the rendering API replacingdrawTiles()in OpenFL 8), doesn't support them. In some cases, blend modes may be emulated using shaders. An example of this can be seen in our BlendModeShaders demo. - Like already the case in OpenFL 3.6.1 + Next, the
flixel.effects.postprocessAPI is not supported in OpenFL 8. As a replacement, a shader filter can be applied to theFlxGameinstance or aFlxCameraas shown in the Filters demo. - OpenFL 3.6.1 with
-Dnexthad support for per-sprite, per-camera or game-wide GLSL shaders. All of these are still fully supported, but the syntax has changed a bit.
Here's a simple example of a shader found in FlxBunnyMark:
With OpenFL 3.6.1 + Next:
import openfl.display.Shader;
class Invert extends Shader
{
@fragment var fragment = '
void main()
{
vec4 color = texture2D(${Shader.uSampler}, ${Shader.vTexCoord});
gl_FragColor = vec4((1.0 - color.r) * color.a, (1.0 - color.g) * color.a, (1.0 - color.b) * color.a, color.a);
}';
public function new()
{
super();
}
}
HAXE
With OpenFL 8:
import flixel.system.FlxAssets.FlxShader;
class Invert extends FlxShader
{
@:glFragmentSource('
#pragma header
void main()
{
vec4 color = flixel_texture2D(bitmap, openfl_TextureCoordv);
gl_FragColor = vec4((1.0 - color.r) * color.a, (1.0 - color.g) * color.a, (1.0 - color.b) * color.a, color.a);
}'
)
public function new()
{
super();
}
}
HAXE
To summarize the differences, shaders should...
- extend
flixel.system.FlxAssets.FlxShaderinstead ofopenfl.display.Shader - use
@:glFragmentSource()metadata for the shader source rather than a@fragment var - have
#pragma headerbeforemain()
Attributes have changed as follows:
| With OpenFL 3.6.1 + Next | With OpenFL 8 |
|---|---|
${Shader.uSampler} |
bitmap |
${Shader.vTexCoord} |
openfl_TextureCoordv |
${Shader.uTextureSize} |
openfl_TextureSize |
You may also have noticed that in the invert shader example, texture2D() has been replaced with flixel_texture2D(). The former still works, but when using flixel_texture2D() in per-sprite shaders, the alpha and color transforms of a FlxSprite are already applied on the returned color, which was previously not supported. The effect of this can be seen when activating shaders as well as toggling "Simple" to "Complex" in FlxBunnyMark:
| With OpenFL 3.6.1 + Next | With OpenFL 8 |
|---|---|
![]() |
![]() |
Further shader examples can be found in these demos, which are all compatible with both OpenFL 3.6.1 + Next and OpenFL 8:
4.2.0
FlxTween.manageris nowFlxTween.globalManager.FlxTimer.manageris nowFlxTimer.globalManager.FlxCamera's scroll bounds now account forzoom. This means that you may need to adjust calls tosetScrollBounds(),setScrollBoundsRect()or changes to theminScrollX/Y/maxScrollX/Yproperties if they manually accounted for zoom.- The
activevariable of objects inflixel.util.helpersnow defaults totrueinstead offalse.
4.0.0
This guide is intended for users upgrading projects from version 3.3.x to 4.0.0. For non-breaking changes, please refer to the changelog.
The minimum required Haxe version for this release is 3.2.0.
A lot of changes can be handled with a simple find-and-replace in the editor of your choice.
elapsed argument added to update()
The function signature of update() changed to update(elapsed:Float). FlxG.elapsed is still available, but it is recommended to use the argument value instead.
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
override public function update():Void |
override public function update(elapsed:Float):Void |
super.update(); |
super.update(elapsed); |
x += 100 * FlxG.elapsed; |
x += 100 * elapsed; |
Introduction of flixel.math
A new flixel.math package was added. A number of flixel.util classes have been moved there:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
import flixel.util.FlxMath |
import flixel.math.FlxMath |
import flixel.util.FlxPoint |
import flixel.math.FlxPoint |
import flixel.util.FlxVector |
import flixel.math.FlxVector |
import flixel.util.FlxRect |
import flixel.math.FlxRect |
import flixel.util.FlxAngle |
import flixel.math.FlxAngle |
import flixel.util.FlxVelocity |
import flixel.math.FlxVelocity |
import flixel.util.FlxRandom |
import flixel.math.FlxRandom |
Move of "typed" classes:
Typed classes have been moved into the modules of the non-typed versions:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
import flixel.group.FlxTypedGroup |
import flixel.group.FlxGroup |
import flixel.group.FlxTypedSpriteGroup |
import flixel.group.FlxSpriteGroup |
import flixel.effects.particles.FlxTypedEmitter |
import flixel.effects.particles.FlxEmitter |
import flixel.ui.FlxTypedButton |
import flixel.ui.FlxButton |
Changed integer constants to enums:
ActionScript 3 does not have enums, which is why a lot of these "value sets" were implemented using integer constants. For improved type-safety and to better fit the Haxe coding style, they have been converted to enums:
As long as it's not ambiguous, Haxe allows using just the enum value name without the enum's name. In the first case, the enum also does not need to be imported. For example, this means that both of these syntaxes are valid:
FlxG.camera.follow(LOCKON);
FlxG.camera.follow(FlxCameraFollowStyle.LOCKON);
HAXE
Which of these two styles is used is mostly a matter of personal preference.
FlxCamera shake modes:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxCamera.SHAKE_BOTH_AXES |
flixel.util.FlxAxes.XY |
FlxCamera.SHAKE_HORIZONTAL_ONLY |
flixel.util.FlxAxes.X |
FlxCamera.SHAKE_VERTICAL_ONLY |
flixel.util.FlxAxes.Y |
FlxCamera follow styles:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxCamera.STYLE_LOCKON |
FlxCameraFollowStyle.LOCKON |
FlxCamera.STYLE_NO_DEAD_ZONE |
FlxCameraFollowStyle.NO_DEAD_ZONE |
FlxCamera.STYLE_PLATFORMER |
FlxCameraFollowStyle.PLATFORMER |
FlxCamera.STYLE_SCREEN_BY_SCREEN |
FlxCameraFollowStyle.SCREEN_BY_SCREEN |
FlxCamera.STYLE_TOPDOWN |
FlxCameraFollowStyle.TOPDOWN |
FlxCamera.STYLE_TOPDOWN_TIGHT |
FlxCameraFollowStyle.TOPDOWN_TIGHT |
FlxText border styles:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxText.BORDER_NONE |
FlxTextBorderStyle.NONE |
FlxText.BORDER_OUTLINE |
FlxTextBorderStyle.OUTLINE |
FlxText.BORDER_OUTLINE_FAST |
FlxTextBorderStyle.OUTLINE_FAST |
FlxText.BORDER_SHADOW |
FlxTextBorderStyle.SHADOW |
FlxTilemap auto-tiling options:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxTilemap.ALT |
FlxTilemapAutoTiling.ALT |
FlxTilemap.AUTO |
FlxTilemapAutoTiling.AUTO |
FlxTilemap.OFF |
FlxTilemapAutoTiling.OFF |
FlxBar fill directions:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxBar.FILL_BOTTOM_TO_TOP |
FlxBarFillDirection.BOTTOM_TO_TOP |
FlxBar.FILL_HORIZONTAL_INSIDE_OUT |
FlxBarFillDirection.HORIZONTAL_INSIDE_OUT |
FlxBar.FILL_HORIZONTAL_OUTSIDE_IN |
FlxBarFillDirection.HORIZONTAL_OUTSIDE_IN |
FlxBar.FILL_LEFT_TO_RIGHT |
FlxBarFillDirection.LEFT_TO_RIGHT |
FlxBar.FILL_RIGHT_TO_LEFT |
FlxBarFillDirection.RIGHT_TO_LEFT |
FlxBar.FILL_TOP_TO_BOTTOM |
FlxBarFillDirection.TOP_TO_BOTTOM |
FlxBar.FILL_VERTICAL_INSIDE_OUT |
FlxBarFillDirection.VERTICAL_INSIDE_OUT |
FlxBar.FILL_VERTICAL_OUTSIDE_IN |
FlxBarFillDirection.VERTICAL_OUTSIDE_IN |
FlxG.html5 browser types:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
HTML5FrontEnd.INTERNET_EXPLORER |
FlxBrowser.INTERNET_EXPLORER |
HTML5FrontEnd.CHROME |
FlxBrowser.CHROME |
HTML5FrontEnd.FIREFOX |
FlxBrowser.FIREFOX |
HTML5FrontEnd.SAFARI |
FlxBrowser.SAFARI |
HTML5FrontEnd.OPERA |
FlxBrowser.OPERA |
Changed String constants to abstract enums:
Some static String constants have been changed to abstract enums. This is not a breaking changes, since the old String values are still compatible, but for the sake of type safety it is recommended to use the enum values instead:
As with regular enums, the enum name may be omitted.
FlxText alignment:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
text.alignment = "left"; |
text.alignment = FlxTextAlign.LEFT; |
text.alignment = "center"; |
text.alignment = FlxTextAlign.CENTER; |
text.alignment = "right"; |
text.alignment = FlxTextAlign.RIGHT; |
FlxG.keys keys:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxG.keys.anyPressed(["SPACE", "W"]) |
FlxG.keys.anyPressed([FlxKey.SPACE, FlxKey.W]) |
FlxG.keys.anyPressed(["SPACE", "W"]) |
FlxG.keys.anyPressed([SPACE, W]) |
FlxSprite:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
getScreenXY() |
getScreenPosition() |
cachedGraphics |
graphic |
resetFrameBitmaps() |
removed (set dirty to true to regen graphic) |
getFlxFrameBitmapData() |
updateFramePixels() |
loadGraphicFromTexture() |
removed (assign a frames collection to frames) |
loadRotatedGraphicFromTexture() |
removed (assign a frames collection to frames) |
FlxCamera:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
bounds |
minScrollX, minScrollY, maxScrollX and maxScrollY |
setBounds() |
setScrollBoundsRect() |
follow()'s Offset argument |
removed |
FlxTilemap:
loadMap() has been split up into loadMapFromArray() and loadMapFromCSV().
FlxGroup:
callAll() and setAll() have been removed - use forEach() instead:
// 3.3.x
group.setAll("scrollFactor", FlxPoint.get(0, 0));
group.callAll("kill");
HAXE
// 4.0.0
group.forEach(function(basic:FlxBasic)
{
basic.scrollFactor.set(0, 0);
basic.kill();
});
HAXE
flixel.input.gamepad:
The hardware IDs of the different controller types are now mapped to a common FlxGamepadInputID. This avoids the need of having to handle multiple controller types - this now happens automatically under the hood.
// 3.3.x
if (gamepad.pressed(XboxButtonID.A) ||
gamepad.pressed(OUYAButtonID.O) ||
gamepad.pressed(LogitechButtonID.TWO)) {}
HAXE
// 4.0.0
if (gamepad.anyPressed([FlxGamepadInputID.A])) {}
// or
if (gamepad.pressed.A) {}
HAXE
It is still possible to use the IDs from the flixel.input.gamepad.id classes via the functions with the Raw suffix.
Because of the poor driver support, the PS3 ID class / support for PS3 controllers have been removed.
FlxTimer:
Timers cannot be started right at construction anymore, instead you need to call start():
// 3.3.x
new FlxTimer(time, onComplete, loops);
HAXE
// 4.0.0
new FlxTimer().start(time, onComplete, loops);
HAXE
FlxPath:
FlxPath#start() no longer takes a FlxObject argument, instead, FlxObject now has a path property. This means FlxObject takes care of updating the path, taking care of the issue that paths are not paused along with the objects they work on in substates.
// 3.3.x
var path = new FlxPath().start(object, points);
HAXE
// 4.0.0
object.path = new FlxPath().start(points);
HAXE
FlxColor / FlxColorUtil refactor:
FlxColor is now an abstract, which means it can be used like an object, while the underlying type is still a regular Int. The static FlxColorUtil functions can now be used as member methods or properties:
// 3.3.x
var color:Int = 0x008080;
trace(FlxColorUtil.getGreen(color));
HAXE
// 4.0.0
var color:FlxColor = 0x008080;
trace(color.green);
HAXE
The amount of colors presets (FlxColor.RED etc..) has been reduced.
FlxEmitter refactor:
FlxEmitterExt has been merged into FlxEmitter. For circular emitters, FlxEmitterMode.CIRCLE can be used.
Most properties are now FlxRangeBounds objects which have a min and a max FlxRange object.
The separate color component Bounds have been merged into a FlxRangeBounds<FlxColor>.
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
at() |
focusOn() |
on |
emitting |
FlxParticle changes:
Most properties are now FlxRange objects which have a start and an end value (for example velocityRange).
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
maxLifespan |
lifespan |
lifespan |
age (counts up instead of down) |
FlxRandom refactor:
FlxRandom can now be instantiated and the static functions are now member methods. A pre-created instance is available via FlxG.random.
Some methods have also been renamed or removed:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxRandom.intRanged(min, max) |
FlxG.random.int(min, max) |
FlxRandom.floatRanged(min, max) |
FlxG.random.float(min, max) |
FlxRandom.chanceRoll(chance) |
FlxG.random.bool(chance) |
FlxRandom.weightedGetObject() |
removed (getObject() now has a range argument) |
FlxRandom.colorExt() |
removed |
FlxAngle changes:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
FlxAngle.getAngle(point1, point2) |
point1.angleBetween(point2) |
FlxAngle.angleLimit() |
removed (use FlxMath.bound() instead) |
There have been several changes to FlxAngle.rotatePoint():
- the y-axis is no longer inverted
- rotation is now clockwise
- moved to
FlxPoint(rotate())
// 3.3.x
var angle = 45;
var point = FlxPoint.get(10, 5);
FlxAngle.rotatePoint(x, y, pivotX, pivotY, angle, point);
HAXE
// 4.0.0
var angle = 45;
var point = FlxPoint.get(10 + x, 5 + y);
var pivot = FlxPoint.weak(pivotX, pivotY);
point.rotate(pivot, angle);
HAXE
FlxMath changes:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
newAmount = FlxMath.wrapValue(value, amount, max + 1) |
newAmount = FlxMath.wrapValue(value + amount, min, max) |
FlxMath.getDistance(point1, point2) |
point1.distanceTo(point2) |
FlxMath.MIN_VALUE |
FlxMath.MIN_VALUE_FLOAT |
FlxMath.MAX_VALUE |
FlxMath.MAX_VALUE_FLOAT |
Other:
| HaxeFlixel 3.3.x | HaxeFlixel 4.0.0 |
|---|---|
import flixel.text.FlxTextField |
import flixel.addons.text.FlxTextField |
FlxPoint#inFlxRect() |
FlxPoint#inRect() |
FlxRect#containsFlxPoint() |
FlxRect#containsPoint() |
flixel.plugin.MouseEventManager |
flixel.input.mouse.FlxMouseEventManager |
flixel.util.loaders.CachedGraphics |
flixel.graphics.FlxGraphic |
FlxArrayUtil.getRandom() |
FlxG.random.getObject() |
FlxVelocity's accelerateTowards*()-functions now only take a single maxSpeed argument (instead of x and y).
The complete option of FlxTween is now called onComplete.
flixel-addons
Not all flixel-addons changes are covered here. Please check the changelog for the rest.
FlxNapeState refactor:
FlxNapeState is now FlxNapeSpace and no longer extends FlxState. This makes it possible to use the flixel.addons.nape package along with other FlxState subclasses (for example FlxUIState).
// flixel-addons 1.x.x
import flixel.addons.nape.FlxNapeState;
class PlayState extends FlxNapeState
{
override public function create():Void
{
super.create();
}
}
HAXE
// flixel-addons 2.0.0
import flixel.FlxState;
import flixel.addons.nape.FlxNapeSpace;
class PlayState extends FlxState
{
override public function create():Void
{
super.create();
FlxNapeSpace.init();
}
}
HAXE

