CitrusEngine架构详解

这是citrus的物理架构截图。下面我详细给大家介绍下citrus的程序架构。
我们知道关卡是继承于state的,相对应的state有Away3DState,BlittingGameState,State,StarlingState
在state里有一个protected方法
protected function createView():ACitrusView
{ return new StarlingView(this); }
这个方法用来创建citrus的渲染基类。citrus的最底层容器是基于ACitrusView,但你不能拿它装载可视对象,因为它不继承于任何容器,相当于一个抽象类。
继承于ACitrusView的有如下Away3DView(3D渲染),BlittingView(位图渲染),SpriteView(sprite渲染),StarlingView(stage3D渲染)。
ACitrusView源码
package citrus.view { import citrus.math.MathVector; import citrus.utils.LoadManager; import flash.geom.Rectangle; import flash.utils.Dictionary; /** * This is an abstract class that is extended by any view managers, such as the SpriteView. It provides default properties * and functionality that all game views need, such as camera controls, parallaxing, and graphics object displaying and management. * * <p>This is the class by which you will grab a reference to the graphical representations of your Citrus Objects, * which will be useful if you need to add mouse event handlers to them, or add graphics effects and filter.</p> * * <p>The CitrusView was meant to be extended to support multiple rendering methods, such as blitting, or even Stage3D thanks to Starling and Away3D. * The goal is to provide as much decoupling as possible of the data/logic from the view.</p> */ public class ACitrusView { /** * This is the manager object that keeps track of the asynchronous load progress of all graphics objects that are loading. * You will want to use the load manager's bytesLoaded and bytesTotal properties to monitor when your state's graphics are * completely loaded and ready for revealing. * * <p>Normally, you will want to hide your state from the player's view until the load manager dispatches its onComplete event, * notifying you that all graphics have been loaded. This is the object that you will want to reference in your loading screens. * </p> */ public var loadManager:LoadManager; public var camera:ACitrusCamera; protected var _viewObjects:Dictionary = new Dictionary(); protected var _root:*; protected var _viewInterface:Class; /** * There is one CitrusView per state, so when a new state is initialized, it creates the view instance. * You can override which type of CitrusView you would like to create via the <code>State.createView()</code> protected method. * Thanks to the State class, you have access to traditional flash display list, blitting and Away3D. * If you want to target Starling you have to use the StarlingState class. */ public function ACitrusView(root:*, viewInterface:Class) { _root = root; _viewInterface = viewInterface; loadManager = new LoadManager(); } public function destroy():void { loadManager.destroy(); } /** * This should be implemented by a CitrusView subclass. The update method's job is to iterate through all the CitrusObjects, * and update their graphical counterparts on every frame. See the SpriteView's implementation of the update() method for * specifics. */ public function update():void { } /** * The active state automatically calls this method whenever a new CitrusObject is added to it. It uses the CitrusObject * to create the appropriate graphical representation. It also tells the LoadManager to begin listening to Loader events * on the graphics object. */ public function addArt(citrusObject:Object):void { if (!(citrusObject is _viewInterface)) return; var art:Object = createArt(citrusObject); if (art) _viewObjects[citrusObject] = art; //Recurses through the art to see if it can find a loader to monitor if (loadManager.onLoadComplete.numListeners > 0) //only do this if someone is listening loadManager.add(art); } /** * This is called by the active state whenever a CitrusObject is removed from the state, effectively also removing the * art representation. */ public function removeArt(citrusObject:Object):void { if (!(citrusObject is _viewInterface)) return; destroyArt(citrusObject); delete _viewObjects[citrusObject]; } /** * Gets the graphical representation of a CitrusObject that is being managed by the active state's view. * This is the method that you will want to call to get the art for a CitrusObject. * * <p>For instance, if you want to perform an action when the user clicks an object, you will want to call * this method to get the MovieClip that is associated with the CitrusObject that you are listening for a click upon. * </p> */ public function getArt(citrusObject:Object):Object { if (!citrusObject is _viewInterface) throw new Error("The object " + citrusObject + " does not have a graphical counterpart because it does not implement " + _viewInterface + "."); return _viewObjects[citrusObject]; } /** * Gets a reference to the CitrusObject associated with the provided art object. * This is useful for instances such as when you need to get the CitrusObject for a graphic that got clicked on or otherwise interacted with. * @param art The graphical object that represents the CitrusObject you want. * @return The CitrusObject associated with the provided art object. */ public function getObjectFromArt(art:Object):Object { for (var object:Object in _viewObjects) { if (_viewObjects[object] == art) return object; } return null; } /** * A CitrusView subclass will extend this method to provide specifics on how to create the graphical representation of a CitrusObject. * @param citrusObject The object for which to create the art. * @return The art object. * */ protected function createArt(citrusObject:Object):Object { return null; } /** * A CitrusView subclass will extend this method to update the graphical representation for each CitrusObject. * @param citrusObject A CitrusObject whose graphical counterpart needs to be updated. * @param art The graphics object that will be updated based on the provided CitrusObject. */ protected function updateArt(citrusObject:Object, art:Object):void { } /** * A CitrusView subclass will extend this method to destroy the art associated with the provided CitrusObject. */ protected function destroyArt(citrusObject:Object):void { } } }
下面我们来看ACitrusView的构造函数
1 public function ACitrusView(root:*, viewInterface:Class) 2 { 3 _root = root; 4 _viewInterface = viewInterface; 5 6 loadManager = new LoadManager(); 7 }
第一个参数root,没错。它才是真正的可视容器。然后你可以往里面添加各种各样的CitrusObject了。
同样CitrusObject也是个抽象类,你可以继承它并组合一个view对象。
浙公网安备 33010602011771号