如果你想作一個關卡,總寬有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.好了之後,關掉Box2D的debug,你就可以看到一個完整的遊戲。= 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";
最後你會發現一個很蠢的現象,就是場景根據鏡頭移動,不過你的記分欄位,與生命值欄位居然也一起跟的動了....
我們希望他應該一直都在同一個位子才對。原因是你的記分欄(_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專案
沒有留言:
張貼留言