1. 程式人生 > >Web前端可以轉行做遊戲嗎?

Web前端可以轉行做遊戲嗎?

其他 drawrect num 要掌握 微信 ask 繪制 his and

作者:ManfredHu
鏈接:http://www.manfredhu.com/2018/03/15/31-laya-game-tips/index.html
聲明:版權所有,轉載請保留本段信息,謝謝大家

技術分享圖片LayaBox

Web前端最近都在跨界!!現在又伸手到遊戲領域了。但是真的那麽好跨界嗎?請讓我一一道來。

Canvas和WebGL的出現其實讓Web遊戲有了實現的可能,但是讓我們用ctx一個個畫,效率還是低了點,所以需要遊戲引擎。它幫助我們去動態渲染遊戲每一幀的元素。

業界比較著名的幾個H5遊戲引擎,有Egret(白鷺),Layabox,Three.js,coco2d-js等等,詳情可以看知乎的回答。

因為我們團隊不是一開始做遊戲的,我們是傳統意義上的前端團隊,從web發家的,起初做的是電商類的業務——拍拍。所以這裏我們綜合幾家遊戲引擎,選擇了Layabox。
有如下有點吧:

  1. LayaAir是一個優秀的適用於多端的遊戲引擎,配備有豐富的組件,有自己的IDE可以快速構建布局等,不需要寫類似CSS的代碼
  2. 支持html的頁面渲染,就是說你可以讓遊戲引擎跟web頁面,混用(這在一些類似文本的頁面非常有用)
  3. 支持2D、3D甚至VR方面的開發。性能也足夠優秀
  4. 對Web前端普遍的上手難度也較其他引擎框架簡單很多
  5. 不需要寫重構(CSS)代碼

其實我們團隊之前也是做得H5競猜小遊戲,不過是基於DOM的,用CSS3做動畫。但是發現CSS3操作復雜動畫,有很多缺點:

  1. 復雜動畫支持度非常差
  2. 頁面元素太多,渲染性能差
  3. 很多復雜的需求做起來很耗時
  4. 玩家手機容易發燙(頁面元素多,動畫復雜)

因此,我們經過預研和討論,果斷走出傳統Web的開發模式,擁抱傳統的遊戲開發!!當然這裏肯定不是一帆風順的,從Web前端轉向遊戲開發,還是有非常多的坑點的。

首先需要擺脫HTML和CSS,你不是在做頁面,你是在做一個遊戲!!遊戲的邏輯占據了一個遊戲80%的工作量,所以你很多時候是在寫JavaScript代碼,這不是問題,其次,你需要擁有面向對象編程的思想。這可能是很多老前端欠缺的,因為JavaScirpt說到底是一門面向函數、面向過程的語言。大家知道模塊化,但是卻還是習慣寫function

而不是ES6的class

這裏因為平臺也在轉型向ES6靠近,所以大膽采用了ES6+Babel+Webpack的模式,甚至於在做Weex、小程序、Web三端融合。即一份代碼,可以在三個平臺跑。扯的有點遠哈,下面開始正文,我們不說用法,具體是說一些坑點,和優缺點對比。

遊戲引擎不適用的地方

遊戲引擎這東西在動畫一塊是真心好用,可以高度還原設計師的動畫,可是其沒有網頁的排版布局,更多的布局應該是通過x、y、更改pivot、anchor屬性來實現。
CSS可以很快速的通過代碼進行相關布局(flex、float、position等屬性),網頁那種自上而下的內容排版可以自動適應內容,對文字處理十分便捷。

針對各自的優缺點,從實現的便捷性來說,遊戲主場景(動畫極多)的情況下,為了提高用戶的體驗,應該用遊戲引擎來寫。
而對一些活動浮層、投註記錄、遊戲規則等有大量圖片文本的頁面,應該用傳統的Web網頁來編寫,這樣才是物盡其用的做法。

在這個背景下,遊戲開發的前端需要掌握多好幾種技能——簡單的遊戲開發的技能、重構部分的構建技能(團隊大前端的趨勢下,去除重構崗位,重構工作由前端接管),可以說工作量翻了一倍。但是在業務側來考慮,因為減少了相關的中間環節,需求叠代可以更快速的落地。

Laya的IDE使用要註意的地方

LayaIDE提供一個組件庫,如list列表,tab按鈕切換等等簡單的Web組件,可以直接拖拽使用而不用自己用代碼再實現一次。
但是IDE自帶的很多組件有坑點,如list組件的selectHandler觸發並不靈敏,數據源重新綁定後會出現點擊無法響應的問題,這個時候要綁定mouseHanlder來代替點擊事件等。
IDE的使用對於不熟悉的人來說上手並不簡單,熟練後可以提高效率。具體可以看官網的介紹。

sceneColor並不起作用

這個屬性是IDE的一個配置屬性,在引用的時候並不會起作用。可以理解為是一個IDE的背景色,可以讓你在用IDE編輯的時候看的更清楚。
技術分享圖片sceneColor並不起作用
如果你需要更換背景色,應該通過繪制一個底部的矩形來實現。

1 this.graphics.drawRect(0, 0, this.stage.width, this.stage.height, ‘#404d6f‘); //設置背景顏色

var和name

var

一般組件view下不管嵌套的層級多深,只要有一個var屬性的命名,都可以用this.xxx來獲取到這個var屬性得帶組件的引用,並對其進行邏輯操作。

name

而name在特定的組件內name有自己的命名規則,如list下的box,命名為render,可以自動識別該box為list內部渲染節點,設置list的repeat等值,直接簡便的實現某些功能。
再譬如dialog界面,我們設置btn的name為close、yes、no等值,可以直接實現關閉dialog窗口的功能等等。name在這個組件下面也是唯一的,可以用來區分不同的組件。

top、right對x,y的影響

如果組件設置了top、right等值,在對其進行x,y變化是無效的。
解決方法:IDE通過這些屬性設置好布局要取消掉,會轉化為對應的x、y值,此時可以操作

圖集圖片過大導致圖片加載失敗

之前按照引擎官方人員的建議設置最大合集圖片為2048乘以2048,後面經過我們的測試發現1024寬高比較適配大部分機型,即圖片最大不能超過1024,否則微信手Q會有圖片load時間過長導致失敗的問題。
這裏可能是部分合並的大圖片下載失敗,也可能是全部下載失敗。然後引擎會單獨去下載每個碎片文件,而服務器是沒有這些文件的,導致下載全部返回404。應該盡量避免這種情況發生。

顯示區域與點擊區域並不完全相等

用一句話來說就是:你看到的並不一定是真實的。如我要完成收起按鈕,然後隱藏整個浮層。
但是你明明可以看到,綁定的點擊事件卻沒有觸發。
這是因為這個層級的高度或者寬度太小,被遮擋這部分是不會觸發的。但是是可見的

分離代碼和工程

起初是因為不想在LayaIDE下寫代碼,所以分成了兩部分,後面發現這種形式還是非常OK的,因為Laya工作人員不是傳統前端開發,他們的IDE是類似Atom的Electron做的,所以其實運行起來編碼體驗並不是太好。其次是因為IDE會生成圖片(png)和圖集(atlas)文件,這些圖片類的靜態資源,更新頻率還是非常高的。如果你只需要修改代碼,或者只要修改圖片圖集,發布一次就好了,不需要同時發布兩種。

這樣的分離,代碼你可以按照你喜歡的方式來寫,比如webpack配置工程,比如文件擺放,該怎麽放怎麽放。再把Laya生成的東西拷貝進來就好了。

設計稿和工程大小

這裏我們設計稿和IDE的寬度高度是完全對應的,所以不存在換算的問題。也不需要類似CSS的做REM兼容等等操作。你設定寬度是750,高度會自動拉伸,但是顯示的頁面層級,需要在初始化的時候拉伸一下,不然還是IDE裏面設定的寬高,當然如果你害怕上面提到的點不到,也可以設定一個非常大的值。

Object.assign兼容

Object.assign是ECMAScript標準的合並對象屬性的方法,類似有jQuery的extend等等。
如果你拋棄了jQuery和Zepto等懶得寫extend方法,又擁抱了ES6,那你可以像我這樣找polyfill來兼容,這裏babel官方有個模塊
也可以自己選擇做兼容,在入口開始的時候載入兼容文件就好。

抗鋸齒問題

這個問題是在WebGL下(Canvas不會),會出現graphics.drawCircle繪制的圓環有鋸齒問題。如下圖:
技術分享圖片鋸齒問題
左邊為沒有設置抗鋸齒,右邊設置了抗鋸齒。

1 2 Laya.Config.isAntialias=true; //開啟抗鋸齒,會消耗一些性能 Laya.init(Browser.clientWidth, Browser.clientHeight, WebGL);

mask遮罩不支持抗鋸齒

技術分享圖片有無鋸齒處理的區別
如圖,下邊是沒有優化前的,鋸齒嚴重。上邊那個圖是優化後的,明顯邊框清晰了很多。
這裏之前的思路是矩形頭像和mask遮罩為一個整體在前面,然後內邊框和外邊框層級在後面,但是這樣的話,mask遮罩部分現在laya還不會抗鋸齒,所以這裏對公共頭像組件進行參數擴展,加了zOrder參數。讓邊框蓋在頭像上,就可以達到抗鋸齒的作用。
最後實現的思路如下圖層級所示。
技術分享圖片頭像層級

Laya幾種優化的寫法

用Laya自帶的屬性獲取像素比

1 2 3 //var browserHeight = document.body.scrollHeight * window.devicePixelRatio; var browserHeight = Laya.Browser.height;//會考慮設備像素比,而且會針對特定機型調整補全 `

這個不用自己算了,Laya.Broswer現在可以獲取得到了。簡化了運算過程
技術分享圖片

用.super()方法繼承父類

Laya.class定義的時候會在原型定義.super方法,直接用就好。兩種用法等價,但是看起來.super更簡單把?
可能有一些例子是通過xxx._super.call(this)繼承父類的,其實直接xxx.super(this)就好了。_super還是看成私有屬性好了。

Web前端可以轉行做遊戲嗎?