So what happens when Step is called? First it checks to see if there is a Reset Request pending. A Reset Request would occur if you had asked Flixel to change to a new FlxState. It will also always happen the very first time your game is started.

After reset has finished it carries on with the Step:

Calculates the Mark and FlxG.elapsed values based on the timescale. FlxG.elapsed = FlxG.timeScale * (step / 1000) Calls FlxG.updateSounds – Which handles panning, proximity and amplitude changes in sounds Calls FlxG.updatePlugins – Iterates through the plugins list and if active calls the plugin update method Calls FlxState.update – See below Calls FlxG.updateCameras – Iterates through the cameras Array (on first pass it’ll just have the one default camera in there). If the camera exists and is active it calls update on it, and the cameras flashSprite is moved based on the new x/y coordinates (if changed) or set in / visible. Finally if the FlxDebugger is visible it updates the timer on it.

Remember that this can all happen multiple times. Probably the most important part of it is #4 when it calls FlxState.update. FlxStates extend FlxGroup, they don’t have update functions of their own – but FlxGroup does. So every single object you add into your state (FlxSprites, FlxTileMap, etc) are all added into this one “master” group. Even other groups, Flixel doesn’t care how deeply nested they are.

FlxState.update iterates through every object in members array. Providing the object has exists = true and active = true, it calls 3 functions on it:

preUpdate update postUpdate

Different objects perform different tasks in these three functions. For example an FlxSprite in its preUpdate call will track the last known coordinates for collision purposes, and also check if the sprite was moving on a path. In postUpdate the FlxSprite will update its motion and animation if there is any. Depending on the type of Flixel object depends what happens in these 3 functions.

It’s also well worth mentioning that typically in the update function of your FlxState is where you normally put commands such as FlxG.collide and FlxG.overlap. We will cover this in more detail in a later tutorial, but it’s still useful to know exactly when in the flow they are handled.

FlxGame.onEnterFrame, continued …

After running step and update as many times as the Accumulator wants, it then calls draw once, and ends the onEnterFrame function.

The draw operation is the most expensive part of Flixel, as it’s where it renders all of the cameras, sprites and objects that build-up the visual display. It does so in the following sequence:

Lock Cameras

FlxG.lockCameras is called, iterating through all active cameras. If useBufferLocking is true, then it will lock the bitmapData per camera (note that the default for this is false). It then calls FlxCamera.fill. This does a fillRect on the fill bitmapData object using a colour value of zero, effectively wiping it clean. It then does a copyPixels from fill to FlxCamera.buffer and finally sets FlxCamera.screen.dirty to true.

FlxState.draw

An FlxState doesn’t have a draw method of its own, although you can over-ride i should you need to do something after all of the children draw operations have finished. FlxState extends FlxGroup, which does have a draw method. Whenever you add something to your State, you are effectively adding it to one giant FlxGroup.

The FlxGroup draw method iterates through all objects in the groups members Array. If the object has exists = true and visible = true then it calls their own draw function. Depending on the data type of the object depends what happens next. The following is the draw process for an FlxSprite:

The FlxSprite iterates through all of the cameras For every camera it checks if the sprite is visible within that camera If it is, it then renders the sprite in one of two ways: If the sprite isn’t rotated, or is using baked rotation, and NO scaling or blend modes have been applied – then it does a copyPixel from the FlxSprites framePixels direct to the camera buffer. If the FlxSprite is rotated, scaled, or has a blend mode then it creates a Transform Matrix. This is then translated, scaled and rotated accordingly. Once the matrix is ready is runs FlxCamera.buffer.draw using framePixels and the matrix. This is a considerably more expensive operation, so please try and always used baked rotation. Finally if visualDebug is on it also draws the debug data (such as the bounding box) to FlxG.flashGfxSprite

It will do the above sequence for every single FlxSprite used in your State! And of course not just sprites – but tile maps, buttons, text, etc. So do try and be careful about what you leave laying around in memory. Always make sure you set exists or visible to false when you’re done with an object. Although Flixel is clever enough to not bother doing a copyPixel if the object isn’t in any of the cameras views anyway, it will still avoid all of those checks. And if you’ve got thousands of sprites, that’s a lot of extra baggage you can shed.

However the draw process isn’t finished yet! We’ve just locked and cleaned all the cameras, rendered all the sprites and other objects, so the final two things it does are: