本文由雲+社區發表javascript
使用一個簡單的遊戲開發示例,由淺入深,介紹瞭如何用Laya引擎開發微信小遊戲。css
做者:馬曉東,騰訊前端高級工程師。html
微信小遊戲的推出也快一年時間了,在IEG的遊戲運營活動中,也出現了愈來愈多的以小遊戲做爲載體運營的活動類型,好比遊戲預定,搶先試完等等,都收到了很是良好的效果。前端
在支持微信小遊戲的遊戲引擎中,Cocos,Egret,Laya都對小遊戲的開發提供了不少強大的支持。前段時間正好抽空研究了一下這塊的內容,現作一個總結,針對如何使用Laya引擎開發微信小遊戲給你們作一下介紹。由於時間有限,研究並不深刻, 若有高手路過,忘不吝賜教。java
作個啥遊戲呢?「絕地求生」很火,咱們作個「絕地求死」如何?策劃也很簡單,和絕地求生相反,主角不是跳傘的玩家,而是地面的炮手,大炮要把跳傘的傘兵用大炮一個個都消滅掉。程序員
牛逼的策劃有了,我們進入正題,看看怎麼實現吧!web
微信小遊戲提供了canvas這個遊戲核心組件。利用Canvas能夠在畫布上畫出文字、圖形、圖像等等。 不過講微信小遊戲以前,得先說說H5,在H5時代獲取canvas對象很是簡單,以下圖:算法
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
複製代碼
經常使用的一些API:shell
ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); //繪製圖片
ctx.fillText(text,x,y,maxWidth); //繪製文字
ctx.rect(x,y,width,height); //繪製矩形
ctx.clearRect(x,y,width,height);//清除矩形內像素
ctx.scale(scalewidth,scaleheight);//縮放
ctx.rotate(angle);//旋轉角度
。。。。
複製代碼
微信小遊戲裏,也提供了canvas對象,只不過獲取接口變了:canvas
wx.createCanvas()
複製代碼
其餘H5環境下有的Canvas API,微信環境裏也都有。
Canvas只是一個2D的畫布,要作一個遊戲,動畫總不能少吧?要讓圖片能動起來,這又是怎麼作到的呢?請看下圖:
好吧,動畫其實就是不斷畫圖片,而後擦除,再畫圖片,再擦除的循環過程,肉眼看起來,那就是動起來了。
在古老的電影膠片時代,咱們看到的電影,就是一張一張連續幀的膠片組成的,最後投射到大屏幕上,變成了咱們看到的電影。
可是,動畫是講究幀率的,通常若是能達到每秒60幀,那就和電影同樣是很流暢的動畫效果了。計算公式:1000ms/60fps=16.67ms,這就要求咱們每次動畫裏的業務邏輯計算,都要16.6ms裏完成,不能影響下一幀的顯示,不然就是卡頓,也就被人說這個遊戲好卡,性能好差了。
知道原理了,性能優化具體怎麼作呢?
固然還有不少其餘更多的技巧和手段來提高canvas的性能,在這樣的狀況下若是咱們直接使用canvas去開發一個遊戲,還會面臨好比碰撞算法、物理系統之類的問題。 因此,若是隻用canvas去開發遊戲,就如同你在吃雞遊戲裏,只拿了一把平底鍋,你怎麼和別人正面剛?
因此,咱們須要一把98K把本身武裝起來,那就是使用遊戲引擎開發。
目前支持微信小遊戲的引擎,有Cocos,Egret,Laya,咱們先看下三者的功能比較:
從各類支持度上來說,laya是目前支持度最好的,也據laya側的宣傳,他的性能也是最高的。(關於性能的問題,因外部水軍比較多,在沒有作實際詳細測試前,暫時不發表評價。)
在公司內部,都有三種引擎的遊戲實現,下面是截止5月份的公開數據的引擎佔比:
其實三個引擎都提供了很好的支持度,通常來講,若是原先使用過Cocos實現過APP端遊戲要移植到微信小遊戲端來的,使用Cocos是最好的選擇,若是是從頭開發一款小遊戲,那仍是在Egret和Laya裏選擇一款吧!
前面講了那麼多,都還只是前戲,只是爲了你們對遊戲的開發有個初步的瞭解,從這一節開始咱們就進入正題了。
到 www.layabox.com/ 去下載最新的版本,並進行安裝。目前有1.X版本和2.0版本。(本文使用1.7.20版本作示例)
而後就能夠建立一個新的遊戲項目了,咱們能夠如今選擇建立一個UI示例項目
[ 建立新工程 ]
固然就是給你寫代碼的地方,感受這個編輯器,就是在VSCode的基礎上改的。連最頂上的Code標識都還在。也由於這樣,因此才能很好的支持TypeScript。
[ 代碼模式佈局 ]
爲何要使用TypeScript? 本文不詳細展開比較,只須要了解TypeScript 是Javascript的超集,由於多了個「Type」表示他支持強類型,而且因爲靜態類型化,在寫代碼的時候編輯器就能提示你的錯誤,因此更適合開發遊戲這種邏輯複雜的應用就行了。固然最終TypeScript仍是會像ES6同樣,被編譯成普通的Javascript執行。可是在開發階段管理代碼來講,已經能夠駕馭大型項目了。
就是用來設計UI界面的地方,拖拖拽拽就能夠把遊戲頁面整出來。Laya提供了好多組件,若是有須要的可使用,固然也能夠不用他的組件,本身搞本身的自定義組件。
[ 設計模式佈局 ]
都說做爲一個程序員,買來文房四寶以後,寫下的第一行字,必定是「Hello World」。(我拿着公司剛發的 20週年LAMY記念鋼筆,寫的第一行字,竟然也是「Hello World」,汗~~~)
首先刪掉系統剛纔默認的文件「LayaUISample.ts」,而後新建文件GameMain.ts
import WebGL = Laya.WebGL;
class GameMain {
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;
}
}
new GameMain();
複製代碼
Laya.MiniAdpter.init()
是Laya提供的對小遊戲提供的適配,由於在小程序&小遊戲環境下,並無Bom和DomAPI,好比,沒有window,document, 因此須要這樣一個適配器,對小遊戲的開發方式,進行兼容。
修改bin目錄下的index.html ,刪掉LayaUISample.ts的引用,改成下面的方式:
<!--啓動類添加到這裏-->
<!--jsfile--Main--> <script src="js/GameMain.js"></script> <!--jsfile--Main--> 複製代碼
在index.html裏,提供了不少Laya的類庫,這些類庫,最終會被打包成合並一個code.js. 由於微信小遊戲的體積限制,咱們不須要把全部的庫都加載進來,只選擇咱們須要的庫就行了,用不到的能夠都刪除。
接下來,點擊運行,就會出現模擬器界面了。
[ 運行模擬器 ]
先別管黑乎乎的一團,下面咱們就要增長「Hello World」了。
再次修改GameMain的代碼以下,重點是var txt:Laya.Text = new Laya.Text();
import WebGL = Laya.WebGL;
class GameMain {
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;
//建立Text對象
var txt:Laya.Text = new Laya.Text();
//給Text的屬性賦值
txt.text = "Hello World";//設定文字內容
txt.color = "#ffffff"; //設定顏色
txt.fontSize=20; //設定字體大小
txt.pos(100,200); //設定位置
//將Text對象添加到舞臺
Laya.stage.addChild(txt);
}
}
new GameMain();
複製代碼
在上面的代碼中,咱們給Stage舞臺上,添加了Text對象,而後點擊運行
啊哦,傳說中的HelloWorld終於出現了
Laya的Sprite提供了一個很是簡單的loadImage
方法,能夠即時加載圖片並加載到舞臺上。
//設置舞臺背景色
Laya.stage.bgColor="#1e83e8";
//建立img Sprite精靈
var img:Laya.Sprite = new Laya.Sprite();
//加載顯示圖片,座標位於100,50,並設置寬高 130*108
img.loadImage("demo/paratrooper.jpg",100,50,130,108);
//把圖片添加到舞臺
Laya.stage.addChild(img);
複製代碼
預覽以下,是否是很簡單?
可是這個方法,其實並不實用,在真實項目中,通常會有不少圖片,咱們不會一張一張圖片的去加載,而是預先加載好,再去顯示圖片。也就是咱們經常在遊戲主界面看到的進度條,其實就是在加載資源。
Laya提供一個資源加載器:Laya.loader
,來解決加載的問題。咱們把上面的代碼再修改下,實現先加載完圖片,而後再繪製圖片。
private imgPath1:string="demo/paratrooper.jpg";
private imgPath2:string="demo/shell.jpg";
constructor() {
//.....省略N行代碼
this.renderImage();
//....省略N行代碼
}
renderImage():void{
//定義圖片路徑集合
var resArray=[
{url:this.imgPath1,type:Laya.Loader.IMAGE},
{url:this.imgPath2,type:Laya.Loader.IMAGE}
]
//使用加載器加載圖片路徑
Laya.loader.load(resArray,Laya.Handler.create(this,this.onLoadComplete),Laya.Handler.create(this,this.onLoadProgress))
}
//加載完成後,把圖片繪製到畫布上
onLoadComplete():void{
console.log("加載完成");
var img1:Laya.Sprite = new Laya.Sprite();
img1.graphics.drawTexture(Laya.loader.getRes(this.imgPath1),100,50,100,100);
Laya.stage.addChild(img1);
var img2:Laya.Sprite = new Laya.Sprite();
img2.graphics.drawTexture(Laya.loader.getRes(this.imgPath2),100,300,100,100);
Laya.stage.addChild(img2);
}
//這裏能夠獲取到加載的進度,之後能夠製做進度條
onLoadProgress(percent:number):void{
console.log("percent->"+percent);
}
複製代碼
只是預加載圖片還不夠,實際場景因爲有不少小圖片,因此咱們能夠把這些小圖片拼合成圖集,這就相似在前端在作性能優化的有時候所使用的css sprite精靈圖,這樣製做成圖集,不但加載性能更高,並且也更便於製做幀動畫。
圖集的加載相似這樣:
var resArray=[
{url:"res/atlas/demo.atlas",type:Laya.Loader.ATLAS},
]
Laya.loader.load(resArray,Laya.Handler.create(this,this.onLoadComplete),Laya.Handler.create(this,this.onLoadProgress))
複製代碼
和以前的圖片加載時Laya.Loader.IMAGE
不一樣的是,type變成了Laya.Loader.ATLAS
。
那圖集怎麼製做呢?還有,大量的遊戲界面,真的就靠手動一張圖片一張圖片的顯示嗎? 固然不!由於咱們接下來該瞭解下UI編輯器了。
UI編輯器,固然是用來編輯UI的,大多數的客戶端程序開發環境,都有相似的UI編輯器。點擊左側的
圖標,進入UI編輯器模式,以下圖:
具體UI編輯器的功能介紹,建議仍是看官方文檔,這裏就不贅述了。
5.1建立UI
由於咱們建立的是默認UI項目,因此UI編輯器裏,有一個TestPage.ui,能夠不用管他,咱們建立一個本身的UI。 點擊 文件->新建文件
進入新建頁面窗口,頁面類型有View 和Dialog兩種,由於這裏咱們作的是整個頁面,因此選View。若是你有興趣去看源碼,其實Dialog也是基於View實現的,只不過多了Dialog的一些特性。
若是對這個view後面還有邏輯代碼要寫,建議勾選「建立邏輯類」,這樣就會自動在View目錄下自動建立一個和UI對應的GamePage.ts
[ 新建頁面UI ]
在assets目錄下,新建一個demo資源目錄,把須要的圖片都扔進去,而後在UI編輯器的資源面板最下方找找到刷新按鈕
,新增資源圖片後,必定要記得點下刷新,不然資源面板的內容不會自動刷新。
只要是demo文件下的圖片,都會被自動打包成圖集,路徑就是 res/atlas/demo.atlas
。 不知道有沒有同窗發現,在上面的圖片中,有部分資源顯示「不打包」,這是什麼緣由的?
點擊文件-》項目設置,咱們會看到圖集限制了能被打入圖集的單圖的最大寬高,和最終圖集的最大寬高,默認標準能夠自行修改。超過這個圖集標準的圖片,就不會打包到圖集中去,就須要手動加載了。
[ 請在這裏填寫圖片描述 ]
編輯頁面功能,會用ppt的,應該都會用了,拖個圖片誰不會?直接把資源管理器的圖片,拖到右側場景編輯器裏。此次咱們拖了一個藍天白雲的背景,並在最下方放了一個大炮,看起來還有點意思。
頂部有一排圖標,是用來協助對齊圖片用的,提供了頂部對齊,底部對齊,左對齊,右對齊,中線對齊等等,若是圖片不少,用這個對齊就很方便了。
右側的屬性欄,就比較經常使用了。 var這裏,你能夠給你拖進來的圖片組件,給個變量名,這個變量名,最後會在以前自動生成的邏輯類裏用到。咱們把大炮定個變量名「pao」,後面會用到;x,y,width,height這裏,就是座標和寬高,就不用多說了吧?
UI作好之後,有個重要的工做,就是千萬別忘記導出。不少初學者,常常會忘記這點。導出UI,纔會從新生成圖集和UI相關設置。
導出之後,咱們看laya/pages/GamePage.ui 文件,不用管裏面的詳細內容,裏面就是剛纔咱們拖拽圖片,自動生成的響應配置文件。
下面咱們要把剛纔編輯的GamePage顯示出來,那就回過頭來,再次修改GameMain.ts
class GameMain {
//定義靜態變量 gamePageView
public static gamePageView:view.GamePage;
constructor() {
//...
this.renderImage();
//...
}
renderImage():void{
//資源加載
var resArray=[
{url:"res/atlas/demo.atlas",type:Laya.Loader.ATLAS},
]
Laya.loader.load(resArray,Laya.Handler.create(this,this.onLoadComplete),Laya.Handler.create(this,this.onLoadProgress))
}
onLoadComplete():void{
//初始化view
GameMain.gamePageView = new view.GamePage();
//添加到舞臺
Laya.stage.addChild(GameMain.gamePageView);
}
}
new GameMain();
複製代碼
運行一下,主界面遊戲背景,和大炮都已經架設好了,好的開端,就是成功的一半了。
接下來,根據最初的牛逼策劃,咱們要像pubgm同樣,讓傘兵從天下掉下來,怎麼實現?接着看動畫部分吧!
關注雲+社區,及時獲取下篇更新