CitrusEngine横版游戏开发教程(一)创建游戏
第一步,创建文档类:
文档类须继承自CitrusEngine,如果你想整合Starling,那么继承自StarlingCitrusEngine
下面我们来创建一个HelloWorld:
package { import citrus.core.starling.StarlingCitrusEngine; public class HelloWorld extends CitrusEngine { public function HelloWorld() { setUpStarling(true); state = new GameState(); } } }
切换关卡只须将关卡赋值给state。
第二步,创建关卡:
关卡须继承自对应的State完成,有四个State可供选择:
1.citrus.core.State
2.citrus.core.starling.StarlingState
3.citrus.core.away3d.Away3DState
4.blitting.BlittingGameState
其中4是继承于1的,不同的是BlittingGameState将所有可视对象在一张位图上进行渲染。
下面我们仍然以Starling为例:
package com.cong.level { import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.Contacts.b2Contact; import citrus.core.starling.StarlingState; import citrus.math.MathVector; import citrus.objects.platformer.box2d.Hero; import citrus.objects.platformer.box2d.Sensor; import citrus.physics.box2d.Box2D; import citrus.physics.box2d.Box2DUtils; import citrus.utils.objectmakers.ObjectMakerStarling; import citrus.view.starlingview.AnimationSequence; import starling.extensions.particles.PDParticleSystem; import starling.extensions.particles.ParticleSystem; import starling.text.TextField; import starling.textures.Texture; import starling.textures.TextureAtlas; import com.cong.entity.Mario; import org.osflash.signals.Signal; import flash.display.Bitmap; import flash.geom.Rectangle; /** * @author cong QQ:19312413 */ public class GameState extends StarlingState { public var lvlEnded : Signal; public var restartLevel : Signal; protected var _hero : Hero; [Embed(source="/../embed/Hero.xml", mimeType="application/octet-stream")] private var _heroConfig : Class; [Embed(source="/../embed/Hero.png")] private var _heroPng : Class; [Embed(source="/../embed/Particle.pex", mimeType="application/octet-stream")] private var _particleConfig : Class; [Embed(source="/../embed/ParticleTexture.png")] private var _particlePng : Class; private var _particleSystem : ParticleSystem; protected var _tilesConfig : XML; private var _tiles : Bitmap; protected var _map : XML; public function GameState(tiles : Bitmap) { super(); _tiles = tiles; lvlEnded = new Signal(); restartLevel = new Signal();
//地图文件包含的对象类型,预加载用,没有别的意义
var objects : Array = [Platform, Hero, Coin, Enemy, Gear, MovingPlatform, MovingPathPlatform, Pool, Thorns, Teleporter]; } override public function initialize() : void { super.initialize(); //整合BOX2D var box2D : Box2D = new Box2D("box2D"); box2D.visible = true; box2D.gravity = new b2Vec2(0, 25); add(box2D);
createMap(); } protected function createMap() : void { var texture : Texture = Texture.fromBitmap(_tiles); var mapAtlas : TextureAtlas = new TextureAtlas(texture, _tilesConfig);
//从TMX地图文件读取对象 ObjectMakerStarling.FromTiledMap(_map, mapAtlas); //创建一个Hero对象 _hero = new Hero("mario"); _hero.x = 10; _hero.y = 500; add(_hero); var bitmap : Bitmap = new _heroPng(); texture = Texture.fromBitmap(bitmap); var xml : XML = XML(new _heroConfig()); var sTextureAtlas : TextureAtlas = new TextureAtlas(texture, xml); //getFirstObjectByType顾名思议,获取第一个Type类型的对象 _hero = Hero(getFirstObjectByType(Hero));
//AnimationSequence是一个从TextureAtlas中获取动画序列的集合,下面默认播放idle _hero.view = new AnimationSequence(sTextureAtlas, ["walk", "duck", "idle", "jump", "hurt"], "idle"); _hero.hurtDuration = 500;
//使用摄像头
//参数1:target 绑定的对象,不解释
//参数2:offset 对象处于屏幕的位置,下面我们设置在舞台中间
//参数3:bounds camera的边界
//参数4:easing camera跟随target的缓动系数 view.camera.setUp(_hero, new MathVector(stage.stageWidth / 2, stage.stageHeight / 2), new Rectangle(0, 0, 10000, 10000), new MathVector(.25, .05)); var psconfig : XML = new XML(new _particleConfig()); var psTexture : Texture = Texture.fromBitmap(new _particlePng()); //创建一个粒子对象 _particleSystem = new PDParticleSystem(psconfig, psTexture); _particleSystem.start(); //创建一个Sensor作为关卡结束的标志 var endLevel : Sensor = Sensor(getObjectByName("endLevel")); endLevel.onBeginContact.add(endLevelHandler);
//绑定Sensor的视图 endLevel.view = _particleSystem; } private function endLevelHandler(contact:b2Contact) : void { if (Box2DUtils.CollisionGetOther(Sensor(getObjectByName("endLevel")), contact) is Hero) { lvlEnded.dispatch(); } } override public function update(timeDelta : Number) : void { super.update(timeDelta); } override public function destroy() : void { TextField.unregisterBitmapFont("ArialMT"); super.destroy(); } } }
Citrus用Signal来传递消息的,其原理是函数回调,效率据说比AS3的事件机制要高出3倍。因为Citrus的基类不是继承自sprite,所以用Signal 比较合适。
有关Signal的用法 就不再详述了。没有接触过的童鞋请自行查阅相关资料
下一篇将着重介绍一下CitrusEngine游戏开发图形装箱工具、刚体编辑工具、地图编辑器的使用。