Upgrade Guide 3.x
3.3.0
The minimum Haxe version for this release is 3.1.0.
On flash, gamepad support has been added. For your project to work, you have to modify your Project.xml so that either:
<set name="SWF_VERSION" value="11.8" />is used (min. flash player version 11.8) or<haxedef name="FLX_NO_GAMEPAD" if="flash" />is used.
When compiling to HTML5, make sure to remove <haxelib name="openfl" /> from your Project.xml. This is already being handled in flixel's own include.xml.
| HaxeFlixel 3.2.x | HaxeFlixel 3.3.0 |
|---|---|
| FlxTween.multiVar() | FlxTween.tween() |
| FlxTween.singleVar() | FlxTween.tween() |
| FlxTween.fader(0, 5); | FlxTween.tween(FlxG.sound, {volume: 0}, 5); |
| FlxSound.survive | FlxSound.persist |
| MouseEventManager.addSprite() | MouseEventManager.add() |
| FlxObject.forceComplexRender = true; | FlxObject.pixelPerfectRender = false; |
| FlxText.width | FlxText.fieldWidth |
| FlxSprite.setOriginToCenter() | FlxSprite.centerOrigin() |
| FlxG.safeDestroy() | FlxDestroyUtil.destroy() |
| FlxTilemap.scaleX | FlxTilemap.scale.x |
| FlxTilemap.scaleY | FlxTilemap.scale.y |
| sprite.animation.addByIndicies() | sprite.animation.addByIndices() |
| sprite.animation.addByStringIndicies() | sprite.animation.addByStringIndices() |
| FlxTimer.userData | removed |
| FlxTween.userData | removed |
| FlxG.sound.add() | FlxG.sound.cache() |
There has also been a slight optimization for simple FlxSprites in FLX_RENDER_BLIT mode (flash and HTML5). This might require an additional dirty = true; for the change to show up if you manipulate the sprite's BitmapData directly.
FlxSprite flipping
Flipping sprite graphics now works differently - the flipped variable has been removed, as well as the Reverse parameter of loadGraphic() and loadGraphicFromTexture(). You can now directly manipulate the new flipX and flipY variables (flipping vertically is now possible).
If you want to continue to use facing to flip the graphic (e.g. in a platformer), you can use the following logic:
sprite.setFacingFlip(RIGHT, false, false);
sprite.setFacingFlip(LEFT, true, false);
HAXE
FlxTimer and FlxPath
FlxPath and FlxTimer were being pooled internally, which could lead to buggy behaviour in certain use cases. Due to that, pooling has been removed from these classes.
| HaxeFlixel 3.2.x | HaxeFlixel 3.3.0 |
|---|---|
| start() | new FlxTimer() / FlxPath() |
| run() | start() |
Also, the following API changes have been made for consistency:
| HaxeFlixel 3.2.x | HaxeFlixel 3.3.0 |
|---|---|
| paused | active |
| abort() | cancel() |
3.2.0
| HaxeFlixel 3.1.0 | HaxeFlixel 3.2.0 |
|---|---|
| FlxTween.multiVar(object, vars, duration, { delay: 1}); | FlxTween.multiVar(object, vars, duration, { startDelay: 1}); |
| FlxG.camera.followAdjust(4, 5); | FlxG.cameras.followLead.set(4, 5); |
| FlxTilemap.arrayToCSV() | FlxStringUtil.arrayToCSV() |
| FlxTilemap.bitmapToCSV() | FlxStringUtil.bitmapToCSV() |
| FlxTilemap.imageToCSV() | FlxStringUtil.imageToCSV() |
| FlxMath.computeVelocity() | FlxVelocity.computeVelocity() |
| FlxState.setSubState() | FlxState.openSubState() |
3.1.0
HaxeFlixel 3.1 is a continuation of our efforts of making the API cleaner and more intuitive, keeping the amount of bugs as low as possible and adding new features. It is one of the biggest releases so far.
This page is a summary of all breaking changes - for a more in-depth list of changes, please refer to the changelog.
FlxTypedButton / FlxButton refactor
FlxTypedButton has been completely refactored, which includes the following breaking API changes:
-
A new
FlxButtonEventclass was added for the onDown, onUp, onOver and onOut events. Instead of thesetCallback()-functions, you now set callbacks like this:button.onDown.callback = someFunction;
This class also contains a
soundproperty:button.onDown.sound = FlxG.sound.load("pathToASound");
You might say: "What happened to custom callback arguments? The
callbackhas the typeVoid->Void!"
While that's true, you can still use callback arguments by leveraging function binding:button.onDown.callback = someFunction.bind(1);
In that example,
someFunctionis of typeInt->Voidand will always be called with 1. -
labelOffset:FlxPointis now an array (labelOffsets:Array<FlxPoint>) which uses the button status constants as indices for more control over the button position. -
The highlight frame of the button spritesheet is now ignored by default on mobile devices, since it does not make much sense there - you can't hover over a button on a touchscreen.
-
It is now possible to "swipe-press" a button, which means you can press it if the input (mouse or touch) has been moved over the button and then released. Previously, you could only press a button if the press happened while you were already hovering over the button. This especially makes
FlxVirtualPadmore usable.
FlxG.keys and FlxG.keyboard
In 3.0.0, FlxG.keyboard has been introduced. However, we realized that this does not make for an intuitive API - you can't tell the difference between the two from their name alone. In fact, even if you have been using the two for a while, it still seems confusing.
This is why me merged the two classes again. This required removing the following functions:
FlxG.keyboard.pressed()FlxG.keyboard.justPressed()FlxG.keyboard.justReleased()
You should use the following functions instead:
FlxG.keys.anyPressed()FlxG.keys.anyJustPressed()FlxG.keys.anyJustReleased()
Please note that those functions take an Array<String> instead of a variable amount of Strings. So the following...
if (FlxG.keyboard.pressed("LEFT", "RIGHT")) {}
HAXE
...becomes:
if (FlxG.keys.anyPressed(["LEFT", "RIGHT"])) {}
HAXE
FlxMouse refactor
The following breaking changes were made during the refactor of FlxMouse:
| HaxeFlixel 3.0.x | HaxeFlixel 3.1.0 |
|---|---|
| FlxG.mouse.show(); | FlxG.mouse.visible = true; |
| FlxG.mouse.load(); | |
| FlxG.mouse.hide(); | FlxG.mouse.visible = false; |
| FlxState.useMouse | removed |
Also, the mouse cursor is now visible by default on non-mobile devices.
The middle and right click event listeners are now set up by default, which means FLX_MOUSE_ADVANCED has turned into FLX_NO_MOUSE_ADVANCED.
The recording system and FlxRandom
To put it bluntly... FlxRandom was a bit of a mess in 3.0. Some of the functions were deterministic, others weren't, which as a result made it very difficult to create deterministic games suitable for the recording system.
In 3.1.0, FlxRandom has been refactored to be completely deterministic. A new algorithm for pseudo-random-number-generation was implemented, which makes old replays incompatible / they will have unpredictable results.
Additionally, the following functions have been added to FlxRandom:
weightedPick()weightedGetObject()colorExt()
FlxSprite renamings
A noteworthy amount of fields inside of FlxSprite have been renamed to increase the consistency with other parts of the API:
| HaxeFlixel 3.0.x | HaxeFlixel 3.1.0 |
|---|---|
| loadfromSprite() | loadGraphicFromSprite() |
| setGraphicDimensions() | setGraphicSize() |
| bakedRotation | bakedRotationAngle |
| pixelsOverlapPoint() | overlapsPoint() |
| loadImageFromTexture() | loadGraphicFromTexture() |
| loadRotatedImageFromTexture() | loadRotatedGraphicFromTexture() |
| setColorTransformation() | setColorTransform() |
Scale Modes
HaxeFlixel 3.1.0 introduces scale modes to simplify targeting multiple resolutions. FlxG.scaleMode can be an instance of the following classes:
RatioScaleMode(default!)FillScaleModeFixedScaleModeRelativeScaleModeStageSizeScaleMode
This change made FlxG.autoResize obsolete and it has thus been removed.
You can also write a custom scale mode that extends BaseScaleMode.
Be sure to check out the ScaleModes demo.
FlxTypedGroup.sort()
The way FlxTypedGroup.sort() has been changed for a significant performance improvement. If you want to sort by y, you now have to use the following syntax:
group.sort(FlxSort.byY, FlxSort.ASCENDING);
HAXE
Instead of:
group.sort("y", FlxSort.ASCENDING);
// or
group.sort();
HAXE
If you want to sort by anything other than y, you'll have to write a custom sorting function, as can be seen in this example:
function sortByAlpha(Order:Int, Sprite1:FlxSprite, Sprite2:FlxSprite):Int
{
return FlxSort.byValues(Order, Sprite1.alpha, Sprite2.alpha);
}
// usage on a FlxTypedGroup<FlxSprite>:
group.sort(sortByAlpha);
HAXE
Other breaking changes
| HaxeFlixel 3.0 | HaxeFlixel 3.1 |
|---|---|
| FlxTypedGroup.autoReviveMembers | removed |
| FlxG.gameFramerate | FlxG.updateFramerate |
| FlxG.flashFramerate | FlxG.drawFramerate |
| FlxG.gamepads.get() | FlxG.gamepads.getByID() |
| FlxG.debugger.visualDebug | FlxG.debugger.drawDebug |
| FlxG.paused | removed (didn't have any functionality) |
| FlxArrayUtil.intToString() | FlxStringUtil.toIntArray() |
| FlxArrayUtil.floatToString() | FlxStringUtil.toFloatArray() |
| FlxMisc.openURL() | FlxG.openURL() |
| FlxMisc | removed |
| FlxSoundUtil | removed (use a FlxTimer instead) |
The classes from flixel.system.input have been moved to flixel.input.
FlxPoints in FlxObject and FlxSprite are now read-only / (default, null), which means you need to use .set() on them if you were previously creating new points. The following...
sprite.velocity = new FlxPoint(100, 50);
HAXE
...becomes:
sprite.velocity.set(100, 50);
HAXE
3.0.0
HaxeFlixel 3.0 is an evolution of the original Flixel API and while most of the API is very similar and quickly learnt, it requires some renames and modifications to update your code.
Major changes from version 2.10
We wanted to slim down up the core classes, which meant moving non-essential functionality into separate classes. We've also continued to focus on improving stability and adding features to the engine. Here's a quick overview of the biggest changes:
- Moved animation logic from FlxSprite, into new FlxAnimationController class. All animation logic is now accessed through mySprite.animation, eg:
mySprite.animation.add(...);
mySprite.animation.play(...);
mySprite.animation.frameName = "String";
mySprite.animation.frameIndex = Int;
//inspect the advanced api features such as
addByNames, addByStringIndicies, addByIndicies, addByPrefix, findSpriteFrame, randomFrame ...
-
Added new FlxKeyShortcuts class, which replaces FlxG.keys. FlxG.keys.pressed is no longer a function, it's now an object, ex:
if( FlxG.keys.pressed.ANY ) {...} -
Added new FlxSpriteGroup class, which allows an FlxGroup to behave like an FlxSprite. This is a powerful new construct that will simplify building UI controls.
-
FlxU is now gone, we've moved all its functionality to several utility classes that specific contain functionality, ex: FlxArrayUtil, FlxAngle, FlxMath, FlxRandom, FlxSpriteUtil, FlxVelocity, etc.
-
FlxSprite Filters are now in a separate FlxSpriteFilter utility class.
Package Structure
HaxeFlixel no longer has an org package. Everything is now included as flixel.package.Class. For most cases you can just remove org. from your import statements.
This was a decision the core developers agreed upon, to make the package structure simpler and detach HaxeFlixel from old flash conventions.
FrontEnds and the FlxG refactor
Frontends in HaxeFlixel 3.x are a new structure to the core of Flixel and which tackles the often criticized bloated collection of static methods in FlxG.
Frontends are accessed in FlxG.frontend in a similar fashion to what Flixel devs are used to. Careful thought has been given to organise them into logical shortcuts. This way the api will be easier browse, remember and maintain.
For example in HaxeFlixel 2.x to add a FlxCamera you would use FlxG.addCamera(camera:FlxCamera);, this addCamera method has been moved into a camera frontend with all the other camera related shortcuts.
So the code in HaxeFlixel 3.x to add a FlxCamera is now FlxG.cameras.add(camera:FlxCamera).
The Flixel FrontEnds are as follows:
- FlxG.inputs
- FlxG.console
- FlxG.log
- FlxG.bmpLog
- FlxG.watch
- FlxG.debugger
- FlxG.vcr
- FlxG.bitmap
- FlxG.cameras
- FlxG.plugins
- FlxG.sound
More detail on the FrontEnds can be read on the FrontEnd docs page.
Core Assets
HaxeFlixel has system Assets for its debugger buttons, system sounds, etc. These assets were previously stored in every project in the assets/data folder. HaxeFlixel 3.x uses the OpenFL include.xml in core HaxeFlixel to omit the need to include them in every project.
So you do not need to have system assets anymore, everything in your project's ./assets/* folder should only be the assets you create.
New Debugger and Interactive Console
HaxeFlixel 3.x includes a powerful console and improved debugger. The new debugger system by default redirects the core trace() command to the log. Alternatively you can use FlxG.log.add() , FlxG.watch.add(), FlxG.log.warn and more.
New Flixel Command Line Tools
Our command line tools have been moved to an optional repository, so the old haxelib run flixel new command will not work.
Install the tools from haxelib just like flixel and run setup and follow the prompts:
haxelib install flixel-tools
haxelib run flixel-tools setup
Now you can use the commands with just flixel, try the help command for more info.
flixel help
//see the new template tool options with:
flixel help template
//Shorthand version to create a template with a custom name
flixel tpl -n "CustomProject"
Automatic find and replace
A collection of most of the API name changes were collected for the flixel-tools command line tool.
You can see what it replaces here.
To run the find and replace the command is simple:
flixel convert
FlxG Changes
The main changes that developers will notice are as follows:
| HaxeFlixel 2.x | HaxeFlixel 3.x |
|---|---|
| FlxG.getLibraryName() | FlxG.libraryName |
| FlxG.setDebuggerLayout | FlxG.debugger.setLayout |
| FlxG.log | trace() |
| FlxG.resetDebuggerLayout | FlxG.debugger.resetLayout |
| FlxG.visualDebug | FlxG.debugger.visualDebug |
| FlxG.toggleKeys | FlxG.debugger.toggleKeys |
| FlxG.DEBUGGER_STANDARD | FlxDebugger.STANDARD |
| FlxG.DEBUGGER_MICRO | FlxDebugger.MICRO |
| FlxG.DEBUGGER_BIG | FlxDebugger.BIG |
| FlxG.DEBUGGER_TOP | FlxDebugger.TOP |
| FlxG.DEBUGGER_LEFT | FlxDebugger.LEFT |
| FlxG.DEBUGGER_RIGHT | FlxDebugger.RIGHT |
| FlxG.random | FlxRandom.float |
| FlxG.shuffle | FlxArrayUtil.shuffle |
| FlxG.getRandom | FlxArrayUtil.getRandom |
| FlxG.globalSeed | FlxRandom.globalSeed |
| FlxG.tween | FlxTween.multiVar |
| FlxG.resetInput | FlxG.inputs.reset |
| FlxG.RED | FlxColor.RED |
| FlxG.GREEN | FlxColor.GREEN |
| FlxG.BLUE | FlxColor.BLUE |
| FlxG.PINK | FlxColor.PINK |
| FlxG.WHITE | FlxColor.WHITE |
| FlxG.BLACK | FlxColor.BLACK |
| FlxG.TRANSPARENT | FlxColor.TRANSPARENT |
| FlxG.DEG | FlxAngle.TO_DEG |
| FlxG.RAD | FlxAngle.TO_RAD |
| FlxG.flashGfx | FlxSpriteUtil.flashGfx |
| FlxG.flashGfxSprite | FlxSpriteUtil.flashGfxSprite |
| FlxG.levels | Reg.levels |
| FlxG.scores | Reg.scores |
| FlxG.score | Reg.score |
| FlxG.saves | Reg.saves |
| FlxG.save | Reg.save |
| FlxG.addCamera | FlxG.cameras.add |
| FlxG.useBufferLocking | FlxG.cameras.useBufferLocking |
| FlxG.lockCameras | FlxG.cameras.lock |
| FlxG.renderCameras | FlxG.cameras.render |
| FlxG.unlockCameras | FlxG.cameras.unlock |
| FlxG.removeCamera | FlxG.cameras.remove |
| FlxG.resetCameras | FlxG.cameras.reset |
| FlxG.shake | FlxG.cameras.shake |
| FlxG.bgColor | FlxG.cameras.bgColor |
| FlxG.warn | FlxG.log.warn |
| FlxG.error | FlxG.log.error |
| FlxG.notice | FlxG.log.notice |
| FlxG.advancedLog | FlxG.log.advanced |
| FlxG.clearLog | FlxG.log.clear |
| FlxG.watch | FlxG.watch.add |
| FlxG.unwatch | FlxG.watch.remove |
| FlxG.play | FlxG.sound.play |
| FlxG.playMusic | FlxG.sound.playMusic |
| FlxG.loadSound | FlxG.sound.load |
| FlxG.addSound | FlxG.sound.add |
| FlxG.stream | FlxG.sound.stream |
| FlxG.destroySounds | FlxG.sound.destroySounds |
| FlxG.updateSounds | FlxG.sound.updateSounds |
| FlxG.pauseSounds | FlxG.sound.pauseSounds |
| FlxG.resumeSounds | FlxG.sound.resumeSounds |
| FlxG.music | FlxG.sound.music |
| FlxG.sounds | FlxG.sound.list |
| FlxG.mute | FlxG.sound.muted |
| FlxG.volume | FlxG.sound.volume |
| FlxG.volumeHandler | FlxG.sound.volumeHandler |
| FlxG.keyVolumeUp | FlxG.sound.keyVolumeUp |
| FlxG.keyVolumeDown | FlxG.sound.keyVolumeDown |
| FlxG.keyMute | FlxG.sound.keyMute |
| FlxG.addPlugin | FlxG.plugins.add |
| FlxG.getPlugin | FlxG.plugins.get |
| FlxG.removePlugin | FlxG.plugins.remove |
| FlxG.removePluginType | FlxG.plugins.removeType |
| FlxG.updatePlugins | FlxG.plugins.update |
| FlxG.drawPlugins | FlxG.plugins.draw |
| FlxG.plugins | FlxG.plugins.list |
| FlxG.loadReplay | FlxG.vcr.loadReplay |
| FlxG.reloadReplay | FlxG.vcr.reloadReplay |
| FlxG.stopReplay | FlxG.vcr.stopReplay |
| FlxG.recordReplay | FlxG.vcr.startRecording |
| FlxG.stopRecording | FlxG.vcr.stopRecording |
| FlxG.checkBitmapCache | FlxG.bitmap.checkCache |
| FlxG.createBitmap | FlxG.bitmap.create |
| FlxG.addBitmap | FlxG.bitmap.add |
| FlxG.removeBitmap | FlxG.bitmap.remove |
| FlxG.getCacheKeyFor | FlxG.bitmap.getCacheKeyFor |
| FlxG.getUniqueBitmapKey | FlxG.bitmap.getUniqueKey |
| FlxG.clearBitmapCache | FlxG.bitmap.clearCache |
| FlxG.clearAssetsCache | FlxG.bitmap.clearAssetsCache |