The CitrusEngine main class and its children

When you want to create a game using the Citrus Engine, your Main class will extend the CitrusEngine class. Note it's also possible to integrate in your website a game made with the Citrus Engine via a SWF file, or create subclass which will instantiate and remove the Citrus Engine game.

What does the CitrusEngine class define?

By extending the CitrusEngine class (which extends Flash MovieClip), you've already set up a lot of useful events:

  • Event.ADDED_TO_STAGE calling handleAddedToStage function. It will define stage properties:
    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = StageAlign.TOP_LEFT;
  • Event.ENTER_FRAME calling handleEnterFrame function. This is the main loop.
  • Event.ACTIVATE calling handleStageActivated function. When this function is called, it will automatically set your game in a playing mode.
  • Event.DEACTIVATE calling handleStageDeactivated function. When this function is called, it will automatically set your game in a pausing mode.

All these functions are defined as protected so that you can easily override them to fit your needs.

The CitrusEngine class also defines variables for severals classes: State, LevelManager, AGameData, SoundManager, Console, and Input.

It's really easy and quick to define a GameState extending State class:

import citrus.core.CitrusEngine;
 
public class Main extends CitrusEngine {
 
	public function Main() {			
	}
 
	override protected function handleAddedToStage(e:Event):void
	{
		super.handleAddedToStage(e);
		state = new GameState();
	}
 
}

As for any version, we need to make sure the engine is actually added to the flash display list before doing anything… this is usually not a problem, but in case you want to preload the game from an external swf this will save you a lot of errors, and it's also common practice to wait for a stage explicitly to avoid surprises.

Note the CitrusEngine class is always accessible thanks to a singleton, meaning you can change your game state from everywhere, access input ect. Use it carefully!

var ce:CitrusEngine = CitrusEngine.getInstance();
ce.state = new AnOtherGameState();

The Main loop

The CitrusEngine main loop is based on an Event.ENTER_FRAME function. It switches states if necessary (destroys the previous and creates the new one), then calls update on the current state. In this update loop we calculate a delta time, which is given as a parameter to the State. The State will update all of its game objects.

If the game is DEACTIVATE or if you set playing property to false, it will prevent the main loop from running.

Add a menu

You can quickly add a game menu in your Main class. Even if you're using Stage3D stuff (Starling or Away3D), it's recommended to use display list elements there because they will be added very quickly! Note that when you're using Stage3D, you need to update your graphics on the GPU, which takes some time.

By default, the game state will be displayed at index 0. It can be easily changed thanks to the _stateDisplayIndex protected property from the CitrusEngine class. Don’t forget that the state is added once a new one is created.

Finally, if you use Starling for your game, you must wait for it to be ready before using it (loading assets, or starting a state). For this, you can override the handleStarlingReady public method from StarlingCitrusEngine, which is called when the context3D is ready and the starling root is created. (It's not an event listener, just a practical function.) Example:

override public function handleStarlingReady():void {
 
	assets = new AssetManager(starling.contentScaleFactor);
	assets.enqueue(File.applicationDirectory.resolvePath(formatString("assets/{0}x", starling.contentScaleFactor)));
	assets.loadQueue(function(ratio:Number):void {
 
		if (ratio == 1.0) {
			_starling.stage.addChild(new Hud());
			state = new GameState();
		}
	});
}

StarlingCitrusEngine

If you want to create a game using Starling, your Main class will have to extend StarlingCitrusEngine, which extends CitrusEngine. It adds useful features for handling Starling, like start/stop, context3D management, and a lot more.

Please refer to the multi-resolution article, which explains how to set up StarlingCitrusEngine along with example code.

Away3DCitrusEngine

It's also possible to create 3D games with the Citrus Engine thanks to Away3D. Extend Away3DCitrusEngine which extends CitrusEngine in your Main class. Like StarlingCitrusEngine, Away3DCitrusEngine has a great helper function to set up Away3D:

public function setUpAway3D(debugMode:Boolean = false, antiAliasing:uint = 4, scene3D:Scene3D = null, stage3DProxy:Stage3DProxy = null):void {
 
	_away3D = new View3D(scene3D);
	_away3D.antiAlias = antiAliasing;
 
	if (stage3DProxy) {
		_away3D.stage3DProxy = stage3DProxy;
		_away3D.shareContext = true;
 
		// we're probably using Starling for a 2D menu/interface, we must listen the enter frame on Stage3DProxy
		_away3D.stage3DProxy.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
		removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
	}
 
	addChildAt(_away3D, _stateDisplayIndex);
 
	if (debugMode)
		addChild(new AwayStats(_away3D));
}

This is the basis code to create a game with Away3D and the Citrus Engine:

import citrus.core.away3d.Away3DCitrusEngine;
 
public class Main extends Away3DCitrusEngine {
 
	public function Main() {
	}
 
	override protected function handleAddedToStage(e:Event):void
	{
		super.handleAddedToStage(e);
 
		setUpAway3D(true);
		state = new Away3DGameState();
	}
}

Note it's also possible to combine a 3D game using Away3D with a 2D interface made with Starling thanks to Stage3D Interoperation.

  citrus/citrusengine_class.txt · Last modified: 2018/06/20 12:58 by 213.249.21.190
 
Powered by DokuWiki