本文由雲+社群發表
6. 動畫
6.1 建立傘兵物件
在src目錄下建立一個新目錄role,用來存放遊戲中角色。 在role裡建立一個傘兵Soldier.ts物件檔案。
module role{
export class Soldier extends Laya.Sprite{
constructor(){
super();
this.init();
}
init():void{
var img:Laya.Sprite = new Laya.Sprite();
img.graphics.drawTexture(Laya.loader.getRes("demo/soldier.png"),0,0,100,86);
this.addChild(img);
}
}
}
複製程式碼
修改GamePage.ts,把傘兵加入到遊戲主畫面中去,重點看renderSoldier()
module view{
export class GamePage extends ui.GamePageUI{
private soldier:role.Soldier;
constructor(){
super();
this.init();
}
init():void{
this.renderSoldier();
}
renderSoldier():void{
this.soldier= new role.Soldier();
this.addChild(this.soldier);
}
}
}
複製程式碼
執行起來看下,發現遊戲主畫面上,已經多了一個傘兵(請忽略我的很爛的摳圖,手動捂臉^_~ )
6.2 讓傘兵掉下來
做過前端的應該都明白,傘兵掉下來,就是要啟動一個定時器,不斷修改傘兵的Y座標+1,移動傘兵圖片的位置。原理都知道,但是如何實現呢? 一般定時器有兩種:
- **setInterval:**基於使用者指定時間
- **requestAnimationFrame :**基於瀏覽器幀能力
相比起來,requestAnimationFrame 效能更高,更適合做動畫。但是在遊戲裡會有很多地方都用到定時器,如何管理那麼多定時器,是非常讓人頭疼的事情。所以Laya也提供了自己的定時器的相關實現:Laya.timer
來簡化定時器的使用,這個定時器同樣是基於幀率的,我們來看看這個怎麼用。
修改GamePage如下,重點看Laya.timer.frameLoop
module view{
export class GamePage extends ui.GamePageUI{
private soldier:role.Soldier;
constructor(){
super();
this.init();
}
init():void{
this.renderSoldier();
//建立定時器
Laya.timer.frameLoop(1,this,this.onLoop);
}
renderSoldier():void{
this.soldier= new role.Soldier();
this.addChild(this.soldier);
}
onLoop():void{
//讓傘兵45度下降
this.soldier.y=this.soldier.y+1;
this.soldier.x=this.soldier.x+1;
}
}
}
複製程式碼
來看下效果,看起來還不錯
7. 碰撞
7.1 增加炮彈
下一步,就改是大炮打傘兵了,當然首先得給大炮建立一個炮彈。 Ball.ts
module role{
export class Ball extends Laya.Sprite{
constructor(){
super();
this.init();
}
init():void{
var img:Laya.Sprite = new Laya.Sprite();
img.graphics.drawTexture(Laya.loader.getRes("demo/ball.png"),0,0,45,54);
this.addChild(img);
}
}
}
複製程式碼
在GamePage上新增炮彈
renderBall():void{
this.ball= new role.Ball();
this.ball.pos(162,540);
this.addChild(this.ball);
}
複製程式碼
嗯,炮彈新增成功,不過,貌似有點問題,怎麼炮彈顯示層級在大炮上面了?似乎有點難看?
7.2 調整Sprite層級
還記得前端世界裡神奇的z-index嗎? Laya也有,叫zOrder。調整zOrder的數值,可以調節Sprite的層次(脫了馬甲,我一樣認識你,^_^) 把渲染炮彈部分改一下層級:
renderBall():void{
this.ball= new role.Ball();
this.ball.pos(162,540);
this.pao.zOrder=10; //調高原先大炮的顯示層級
this.addChild(this.ball);
}
複製程式碼
這次炮彈躲在大炮後面去了,一會兒再讓他出來吧!
7.3 點選大炮發射炮彈事件
炮彈向上飛,就和傘兵向下掉一樣,在幀迴圈裡不斷修改y值就可以。但是這次,我們要響應事件了,必須點選大炮,觸發點選事件後,才發射炮彈。
再次修改GamePage.ts,這次的重點是多了 this.pao.on(Laya.Event.MOUSE_DOWN,this,this.onMouseDown);
這個事件監聽
module view{ export class GamePage extends ui.GamePageUI{
private soldier:role.Soldier;
private ball:role.Ball;
private isSendBall:boolean=false;
constructor(){
super();
this.init();
}
init():void{
this.renderSoldier();
this.renderBall();
//給大炮增加事件監聽
this.pao.on(Laya.Event.MOUSE_DOWN,this,this.onMouseDown);
//建立定時器
Laya.timer.frameLoop(1,this,this.onLoop);
}
renderSoldier():void{
this.soldier= new role.Soldier();
this.addChild(this.soldier);
}
renderBall():void{
his.ball= new role.Ball();
this.ball.pos(162,540);
this.pao.zOrder=10;
this.addChild(this.ball);
}
onMouseDown():void{
this.isSendBall=true;
}
onLoop():void{
//讓傘兵45度下降
this.soldier.y=this.soldier.y+1;
this.soldier.x=this.soldier.x+1;
//如果是發射炮彈狀態,炮彈向上發射
if (this.isSendBall){
this.ball.y=this.ball.y-3;
}
}
}
}
複製程式碼
在執行一下看看:
到目前為止,還進行得不錯,就差擊落傘兵了,可憐的傘兵,你的死期就要到了,還差一個碰撞了。
7.4 炮彈與傘兵的碰撞
碰撞演算法常見的有以下這些:
- **矩形碰撞:**矩形圖片接觸碰撞,計算效能最快,但是如果影象並不近似矩形的時候,準確度就不高了。
- **圓形碰撞:**和矩形類似,比如炮彈就是圓的,用圓形檢測,更適合真實情況。
- **多矩形碰撞:**如果影象相對比較複雜,可以拆分為多個矩形,在準確性和效能方面取得平衡。
- **畫素檢測碰撞:**如果需要非常精確的碰撞,就要使用畫素檢測了,這個效能相對就比較低了。
在Laya裡,對於矩形碰撞檢測,提供了Rectangle.intersection()
方法,可以非常方便的進行矩形檢測。
繼續修改GamePage.ts
gameOver():void{
Laya.timer.clear(this,this.onLoop); //停止遊戲幀定時器
this.renderBoom(); //顯示爆炸圖片
this.removeChild(this.soldier); //刪除傘兵
this.removeChild(this.ball); //刪除炮彈
}
onLoop():void{
//讓傘兵45度下降
this.soldier.y=this.soldier.y+1;
this.soldier.x=this.soldier.x+1;
//如果是發射炮彈狀態,這炮彈向上發射
if (this.isSendBall){ this.ball.y=this.ball.y-3;
//使用矩形碰撞判斷,如果炮彈和傘兵碰撞,則遊戲結束
if (this.ball.getBounds().intersection(this.soldier.getBounds())){
this.gameOver();
}
}
}
複製程式碼
再來看下效果:
Boom,傘兵成功被大炮打中,“絕地求死”完美收工!
8. Laya的效能優化
8.1 效能監測工具
Laya已經內建了效能監測工具,只要初始化後執行Laya.Stat.show();
就可以開啟
constructor() {
//TS或JS版本初始化微信小遊戲的適配
Laya.MiniAdpter.init(true,false);
//初始化佈局大小
Laya.init(375,667, WebGL);
//佈局方式設定
Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
Laya.stage.screenMode = Laya.Stage.SCREEN_VERTICAL;
Laya.stage.alignV = Laya.Stage.ALIGN_CENTER;
Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
//開啟效能監測皮膚
Laya.Stat.show();
}
複製程式碼
上面清楚的顯示了目前的FPS、Sprite的數量、DrawCall 、記憶體消耗等,我們優化的目標就是把這些值降低下來。
8.2 優化手段
- 減少Sprite的數量
- 不可見區域的Sprite及時移除
- 靜態內容使用cacheAs=bitmap降低DrawCall
- 使用Laya.Pool管理物件,減少重複建立的效能消耗
- 物件無用時,及時銷燬
- 定時器及時銷燬
- 。。。
具體的優化手段有很多,大家可以在具體的業務開發中不斷的總結提煉。
9. 釋出到微信小遊戲
講了那麼多的Laya,說好的微信小遊戲呢? 不要急,這就來了,Laya生成的程式碼,可以非常方便的釋出到微信小遊戲。
點選
進入釋出介面,在釋出平臺選擇“微信小遊戲”,此時生成可以在微信開發者工具下執行的release/wxgame版本
使用微信開發者工具開啟,已經可以完美執行了。而且我們發現laya把我們剛才寫的程式碼,和Laya的核心庫一起,都被打包成一個code.js了。
[ 微信開發者工具 ]
10. 開發環境相容
可是,作為微信環境下的遊戲,因為code.js是laya自動生成的,我們開發還是必須在laya的開發環境下,但是laya並不支援微信的介面除錯,那我們可以在Laya裡判斷開發環境嗎?
當然可以,用Laya.Browser.onWeiXin
就可以判斷了,比如:
if (Laya.Browser.onWeiXin) {
let wx=Laya.Browser.window.wx;
//執行微信的API邏輯.....
}
複製程式碼
只是除錯起來就有點蛋疼了,得Laya裡寫好,釋出到release/wxgame,再在微信開發者工具裡除錯。
=總結=
總體來說,Laya入門還是比較簡單的,雖然官方也做了很多文件,也有做視訊教程,但是感覺資料還是有點缺,這次自己研究Laya的歷程分享出來,也算是為Laya社群做點貢獻吧!
因為本人接觸Laya的時間並不長,也不是專業的遊戲開發人員,如果有講得不對的,也歡迎及時指出,歡迎大家一起交流。
此文已由作者授權騰訊雲+社群釋出
搜尋關注公眾號「雲加社群」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!