如果你想作一個關卡,總寬有5000以上(瑪莉兄弟一樣),可別真的去設定一個寬5000以上的Satge,實際上在CitrusEngine裏面的世界理論上是不預設的(無限大),我們一開始設定的Stage size (500x400)只是遊戲中畫面鏡頭(Camera)的大小,如下圖示意
實際上只要角色移動時,Camera也跟著移動,就可以做到這樣的效果,一般我們把這功能叫作鏡頭跟隨。想作出這樣的效果相當簡單,因為CitrusEngine已經有提供Camera物件讓你可以直接使用。
請在initialize加上以下這句Camera物件程式碼。
//鏡頭跟隨控制 view.camera.target = hero; //定位在畫面中心點 view.camera.offset.x = 250; view.camera.offset.y = 200;每個State會有一個view,每個view都有個camera,你可以設定他的屬性。
我們只要把camera的target(跟隨目標)設定成 hero物件,然後把畫面定位在stage的中心點,你作可以很容易的作出鏡頭跟隨的效果。你可以輸出並操作看看。
目前這個世界的地板(bottom)只有500px,相當小,一不小心就會掉下無底深淵XD,為了讓角色可以盡情奔馳,我們希望可以把場景作寬闊一點,當然你可以直接延伸你的地板,並且在其他更遠的地方加上平台與金幣....不過如果場景上全部的物件都用程式寫出來,實在是極為麻煩的事,接下來介紹一個讓你輕鬆編輯場景的方法。
首先去官網下載作好的Flsah組件庫
用Flash打開Components.fla這個檔案,這是一個空白的場景,讓你自己編輯你的遊戲物件。
打開這個fla的元件庫,可以看到已經有作好的元件讓你直接使用。
目前我們是使用Box2D物理引擎(別不小心使用到Nape的物件喔!),你可以直接使用元件庫裏面的Box2D物件,把相對應的物件擺放到需要的位置,這樣子就可以很輕鬆的製作你的場景。
我的場景用Platform拉出了直式的世界,Hero一開始是在左小角(藍色),黃色的物件是Coin(金幣),並放置一個Enemy敵人(紅色),為了方便之後使用,特地把最下面的Platform實體名取為bottom,各階梯實體名都取為cloud,之後我就可以用名稱來分辨他們,遊戲開始的時後Hero就可以踏著Platform往上跳。作好了之後直接輸出swf即可。
接下來,我們只要把輸出的swf拿到我們的State去用就好了。
CitrusEngine有提供一個ObjectMaker工具物件,他會自動對應你的swf,然後幫你建立場景。
首先用Loader載入你的swf。
//載入建立的場景
var _loader:Loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onViewLoaded);
_loader.load(new URLRequest("gameState.swf")); //gameState.swf就是我剛剛輸出的swf
載入好了之後用ObjectMaker去建立你的場景
/**
* gameState.swf載入
* @param e
*/
private function onViewLoaded(e:Event):void
{
e.target.removeEventListener(Event.COMPLETE, onViewLoaded);
var _loader:Loader = LoaderInfo(e.target).loader;
//加入Box2D物理引擎
var box2D:Box2D = new Box2D("box2D");
box2D.visible = true; //debug模式開關
add(box2D);
//建立場景
ObjectMakerStarling.FromMovieClip(_loader.content as MovieClip);
_loader.unloadAndStop();
}
Box2D物理引擎是一定要加的,然後我們用ObjectMakerStarling.FromMovieClip去建立從Loader取出的MovieClip。之後把Loader的內容釋放掉。如果你現在輸出的話,你就可以看到你用flash輸出的場景,而且還可以操作,很方便吧!
再來我們對遊戲裏的元素作一些細部的設定。你可以用State的getObjectByName("物件名稱")或getObjectsByType(物件類別)來取得各個元素去設定你想要的View或他的參數。
//加入地板
var bottom:Platform = getObjectByName("bottom") as Platform; //取出名稱為bottom的物件
bottom.view = "500x30.jpg";
//加入角色
var bitmap:Bitmap = new _heroPng();
var texture:Texture = Texture.fromBitmap(bitmap);
var xml:XML = XML(new _heroConfig());
var sTextureAtlas:TextureAtlas = new TextureAtlas(texture, xml);
var hero:Hero = getFirstObjectByType(Hero) as Hero; //取出類別為Hero的物件
hero.acceleration = 0.3; //加速度
hero.maxVelocity = 5; //速度極限
hero.view = new AnimationSequence(sTextureAtlas, ["walk", "duck", "idle", "jump", "hurt"], "idle");
hero.offsetY = -10;
hero.group = 1;
hero.onJump.add(heroOnJump);//跳躍觸發
hero.onGiveDamage.add(heroOnGiveDamage);//攻擊觸發
hero.onTakeDamage.add(heroOnTakeDamage);//被攻擊觸發
//加入一個平台
var _CitrusObjectVec:Vector. = getObjectsByName("cloud"); //取出所有名稱為cloud的物件陣列
var _num:int = _CitrusObjectVec.length;
var _cloud:Platform;
var i:int;
for (i = 0; i < _num; i++)
{
_cloud = _CitrusObjectVec[i] as Platform;
_cloud.view = "200x30.jpg";
_cloud.oneWay = true;
}
//加入一個金幣
_CitrusObjectVec = getObjectsByType(Coin); //取出所有類別為Coin的物件陣列
_num = _CitrusObjectVec.length;
var _coin:Coin;
//加入敵人
var enemy:Enemy = getFirstObjectByType(Enemy) as Enemy; //取出第一個類別為Enemy的物件
enemy.leftBound = 130;
enemy.rightBound = 270;
enemy.view = "Enemy.png";
好了之後,關掉Box2D的debug,你就可以看到一個完整的遊戲。
最後你會發現一個很蠢的現象,就是場景根據鏡頭移動,不過你的記分欄位,與生命值欄位居然也一起跟的動了....
我們希望他應該一直都在同一個位子才對。原因是你的記分欄(_scoreTd)與生命值(_livesTd)都跟遊戲中的物件在同一個View,偏偏一個State又只有一個View,所以你也沒有其他地方可以擺...
其實場景上每個CitrusSprite物件有個屬性叫做parallaxY與parallaxX,他可以讓你控制鏡頭移動時與物件相對移動的比例,一般來說你可以用這個屬性作出遊戲中的遠景與近景移動的距離感(你可以自己實驗看看..),預設是1,你可以把他設成0,這樣就物件就不會跟著鏡頭移動了。(設成0.5的話會有遠景的效果)
//分數欄位
var _scoreTd:CitrusSprite = new CitrusSprite("scoreTd", { view: new TextField(200, 50, "分數:0") , x:80, y:0, group:2 });
_scoreTd.parallaxX = 0;
_scoreTd.parallaxY = 0;
add(_scoreTd);
//生命欄位
var _livesTd:CitrusSprite = new CitrusSprite("livesTd", { view: new TextField(200, 50, "生命:" + citrusEngine.gameData.lives) , x:180, y:0, group:2 } ) ;
_livesTd.parallaxX = 0;
_livesTd.parallaxY = 0;
add(_livesTd);
Demo預覽原始碼下載
Flash遊戲引擎 CitrusEngine (七) 開始你的第一個行動APP遊戲吧 - 開始一個CitrusEngine APP專案





沒有留言:
張貼留言