整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          微信發布小游戲:5年痛徹心扉,向即將起飛的H5創業者

          微信發布小游戲:5年痛徹心扉,向即將起飛的H5創業者致敬!

          ameLook報道 / 12月28日,對國內H5游戲創業者來說是迎來奇跡的一天。

          騰訊28日下午通過多個官方微信公眾號正式公布了“小游戲”,同時上線了15款小游戲產品、其中包含多個騰訊自研的棋牌小游戲,這昭示著騰訊微信正式擁抱H5手游市場,給多年來一直等待H5游戲機遇的游戲開發者送上了終極新年大禮包。而28號全天,已有過萬的國內游戲開發者通過Gamelook的報道了解到這則令全行業振奮的信息。

          目前,更新iOS微信6.6.1最新版的用戶啟動微信已能看到小游戲的開屏登陸頁面(android版在灰度測試中),伴隨微信小游戲公布,騰訊還提供給了小游戲開發者新的開發工具、開發文檔。同時28日下午Cocos、Layabox、白鷺這三個國內主流引擎商都發布了引擎的最新進度,全力支持微信小游戲開發者。

          對于真正在游戲圈有些年頭的從業者,看到微信小游戲的正式登場,真可謂感慨萬千,在這里gamelook首先要向一直堅守在H5這個陣地多年的開發者、創業表示致敬,真的太不容易了。

          微信小游戲:一場遲到5年的機遇,H5創業者歷經千辛萬苦

          gamelook最早開始報道HTML5手游趨勢是在2011年,而更早的關于HTML5移動平臺應用的爭議則要追溯到2010年。現在回憶起過往H5游戲領域發生的大事件真可謂歷歷在目,也真叫創業者痛徹心扉。

          2010年4月,當時還健在的蘋果公司創始人喬布斯曾發表了一篇文章,重點闡述為何蘋果設備不再支持Flash,喬布斯當時說道:“讓第三方(Flash)插足平臺和開發者之間,最終會制造出低標準應用,它會阻礙平臺的擴張和進展。”

          因為蘋果的堅決、google的跟進,Flash在移動端走向了末路,順其自然,全球開發者開始按照蘋果給出的方向:HTML5,勇敢前進。但誰知創業者勇敢追逐的HTML5卻帶來行業長達數年的痛苦。

          2011年,騰訊QQ游戲中心在國內設立了總獎金百萬元的“騰訊移動終端游戲開發大賽”,這是騰訊開始介入HTML5游戲領域的標志性事件,在當時的報名信息中,騰訊即積極鼓勵HTML5移動游戲開發者參與這場創業者選秀。而2011年1月騰訊微信剛剛發布。同時在海外市場,2011年Facebook也開動了自己的代號“斯巴達”的H5游戲平臺建設。

          有著蘋果、騰訊、Facebook這些超級平臺的趨勢指引,其后,諸多國內創業者開始加入了H5游戲創業浪潮之中,當年移動開發者活動中非常火的一個就是創新工場力挺的“HTML5大會”。

          在眾多創業公司中,當年最具有代表性的H5游戲公司叫磊友科技,其創始人黃何曾是騰訊公司產品經理,2010年就早早嗅到了H5的苗頭獲得創新工場投資、之后累計融資超過千萬美元,磊友不僅開發H5跨平臺游戲引擎、還自己開發H5游戲產品,當屬最早的H5明星企業,但誰知磊友也成了H5游戲“概念包袱”最重的創業公司。

          雖然2017年年末的微信小游戲引爆行業,但在gamelook記錄中,早在2012年Q2騰訊高管劉熾平就做了相應的表態,劉熾平當時曾表示:“大型應用軟件將基于本地客戶端,其使用量將非常大,需要不斷發展。這些應用軟件應當具有大量內置特色功能供用戶使用;但同時對于很多用戶不是每天都使用的應用程序或者內容,通過瀏覽器或者HTML5訪問可能是更高效的途徑,因此面向這兩種應用程序的市場將繼續存在。我們嘗試要做的是,參與到這兩個市場里。”

          劉熾平2012年就指出微信、手機QQ、瀏覽器是HTML5應用的載體,但騰訊所設想的非原生APP的第二個應用市場,直到2017年才開始真正著手嘗試。

          5年的間隔,意味著很多,對國內H5游戲創業者來說代表著遭遇一系列的重大挫折。

          蘋果雖然力推HTML5但并不希望原生應用采用H5技術,且對非appstore生態的H5應用和游戲采取了徹底的封堵方式。

          微信H5游戲?其實磊友早在2013年即嘗試過,缺乏蘋果和微信平臺的支持,迎頭而來的是H5游戲遭遇各種技術問題、產品問題,進而是磊友公司不斷轉型,乃至最終消失于行業,令行業扼腕。

          Facebook在海外主導的H5游戲平臺因為多方面原因慘敗,導致海外跟隨Facebook挺進H5游戲市場的一批大公司相繼在手游市場跌倒,這其中典型的就是豪賭H5手游、而錯失早期智能機爆發期的Zynga。

          同時,國內H5引擎代表性公司從當年的磊友,變成了Cocos、白鷺、LAYABOX,典型的H5游戲公司也變成了蝴蝶互動、中手游、37互娛這些更晚進入H5市場的游戲公司。當年磊友沒能解決的技術問題,Cocos、白鷺、LAYABOX用數年的扎實積累、打磨,一個一個攻克,甚至HTML5都已不能代表目前小游戲技術本質。而微信、Facebook經過數年的用戶積累,終于迎來了其移動生態能與蘋果正面磋商的地步。

          5年堅守,是所有參與H5市場每一家公司的執念,最終換來了微信小游戲的正式公布。

          迎頭而來的微信小游戲到底是什么?

          好日子已在眼前,事實上,微信小游戲的公布是整個H5游戲市場最大的爆點,但并不是全行業H5游戲的起點,我們不應忽視手Q、厘米游戲平臺,玩吧,乃至行業內眾多發行商在H5游戲市場上的眾多嘗試。

          但仔細去思考微信小游戲代表著什么?真的是大多數人所認為的用戶紅利么?gamelook并不這么認為。

          用戶紅利其實對目前的國內互聯網來說已叫消耗殆盡,智能機增幅為個位數,其實幾乎所有的用戶已在移動平臺之上。

          微信小游戲的加入,更多意味著流量的再分配、用戶時間的再分配和特定需求的滿足,對騰訊來說手中則是多了一張洗牌整個流量大盤的手段和王牌。

          騰訊目前并沒有徹底壟斷分發,難點有兩個,其一是手機終端廠商各占山頭,其二是非騰訊的超級APP對分發市場的競爭。微信小游戲、以及手Q、瀏覽器小游戲的加入,代表著騰訊有了良好的基礎參與到流量的再分配中,但這種分配是基于各種新的用戶應用場景。而當下移動互聯網,流量的發源地主要是基于內容平臺、和社交平臺。

          而隨著騰訊微信小游戲的發布,即使是出于防守目的、相信非騰訊的超級APP、手機硬件廠商也將加速推進H5游戲平臺布局。最終全行業平臺對H5游戲平臺基礎設施的快速成型,將產生鏈式反應,催生真正適應于H5游戲分發、應用場景的新生態。

          對大家最關心的微信小游戲來說,新的應用場景就是社交化游戲場景、以及新的小游戲分發場景。如果開發者指望騰訊獨代的方式來給小游戲導流,可能有些想當然,以今天微信小游戲上線第一天即發布15款游戲來說,可能后繼微信小游戲的數量會非常龐大,創業者需要認真思考的問題是微信小游戲與原生游戲到底差別在哪里,應用場景到底有何不同才是取勝的關鍵。

          事實上,在微信公布小游戲之前,行業內就有兩個非常鮮活的成功案例啟發過行業微信小游戲該如何做,其一就是這兩年大火的房卡棋牌,其二就是騰訊自己的《王者榮耀》。

          所以雖然微信小游戲給行業帶來了重大的利好,但不應夸大小游戲導流的作用,行業更應該去思考小游戲產品如何適應這種新的社交化生態環境。

          周末,由極光網絡主辦的首期“極光會客廳”正式開門迎客。在本次的“2D小游戲開發實戰技術沙龍”上,極光網絡客戶端主程陳策以及極光網絡項目總監陳源向一眾與會者分享了“大型H5游戲如何登陸微信小游戲”以及“游戲性能優化”的大量研發干貨。

          以下是兩位嘉賓的干貨整理:

          陳策:大型H5游戲如何登陸微信小游戲

          隨著公司業務的發展,我們的項目往往要登陸各種平臺,微信小游戲就是這些平臺的其中之一。

          微信小游戲是微信小程序的一個類目,它即點即玩,無需下載安裝,體驗輕便,可以和微信內的好友一起玩,比如PK,圍觀等。

          但想讓自己的游戲登陸微信小游戲,會有一些方面的限制,下面我們主要說下《大天使之劍H5》這一項目登陸微信小游戲受到的主要限制和解決辦法。

          一、《大天使之劍H5》受到微信小游戲的主要限制

          1.所有分包大小不得超過8M:分包指的是在微信開發工具里上傳的所有資源,包括JS代碼和資源,一共不得大于8M;

          2.單個包的大小不得大于4M:上傳的文件里,不能有大于4M的文件;

          3.JS必須放在分包里才可以運行,加載進來的JS文件只會被當成文本:加載進的JS文本,無法轉成可執行腳本。

          《大天使之劍H5》在登陸微信小游戲前,整個項目大小約有400多M,光JS代碼部分就有大約10M。除邏輯代碼的其它資源(圖片、音效、配置等),可以在游戲運行時進行加載,不用在開發工具里上傳,但約10M的JS代碼部分必須全部上傳。因此,《大天使之劍H5》想登陸微信小游戲,必須縮小JS代碼的大小。

          二、現有壓縮工具UglifyJS部分功能簡介

          Layabox引擎里將項目的AS3部分生成JS時會進行一定的優化,這個功能應該是基于UglifyJS來實現的。其優化內容主要有:

          1.去掉代碼中無效的空白字符

          2.去掉代碼中的注釋

          如圖所示:

          3.把方法中局部變量名縮短

          如圖所示:

          4.代碼格式優化 (把代碼改為更省字符的寫法)

          如圖所示:

          5.壓縮屬性名 (默認不開啟)

          我們先來看看這個例子,這個是一個類,在工具默認不開啟壓縮屬性名稱時,工具就只會壓例子里橙色的兩處X和Y,因為這個是參數,也就是剛才說的方法里定義的變量,this.x,this.y這都是不壓的,因為這個是屬性名。如果類名Point,方法名setTo,屬性名X,Y壓了,那其他使用的地方就要根著一起改,如果代碼里有用到反射來調用的,那就調用不到了。所以壓縮這些名稱是有風險的,這也就是工具默認不壓的原因。那這個功能不就廢了?不會,工具還提供了很多參數讓你可以設置不壓縮的名稱的列表,還允許你定義壓縮的名稱的正則表達式等等,其實還是可以使用的,只是還是要先整出一份針對自己項目的名稱數據出來,整理出來的不壓縮名稱集要和代碼同步進行維護,這樣難度會比較大,所以《大天使之劍H5》項目并沒有使用這個功能。

          小結:

          《大天使之劍H5》項目現有的AS3代碼代碼在Layabox生成JS代碼時,已經默認進行了上述前四點優化:

          • 去掉代碼中的無效的空白字符
          • 去掉代碼中的注釋
          • 方法中的局部變量名縮短
          • 代碼格式優化

          但生成的JS代碼有10M左右,還沒有達到微信小游戲的要求,因此,為了縮小代碼量,我們需要對我們的AS3代碼再做一些優化,從而減少代碼量。

          三、減少程序代碼

          縮小代碼量,最直接的方式就是減少代碼里的字符,這部分所作的優化,是在我們項目的AS3代碼部分所做的優化,這些優化包括以下幾點:

          1.將界面布局的數據改為從外部加載

          Layabox的UI編輯器編輯后,會生成對應的UI類文件,其內容如圖:

          這里面主要內容是UI的布局數據,不用涉及到邏輯,可提取出來。做為文本文件保存,在其對應的界面初始化時再加載,在Layabox中,我們可以通過修改UI模式來做調整:

          我們可以隨意創建一個UI來做測試,如圖所示:

          我們可以看到,新建一個TestPageUI界面,使用內嵌模式生成的TestPageUI.as文件共有3283字節,而使用分離模式,生成的文件只有579字節。圖中右邊綠色部分表示的是減掉的部分代碼,為我們縮小約80%左右的UI布局相關代碼。

          而在《大天使之劍H5》中,UI布局文件目前有931個,使用這種方式幫我們減少了1.8M的代碼。

          2.將類里不使用的導入刪除

          我們在開發時,手誤import進入的一些項目并未使用到的類,需要將這些import刪除。如:import Sprite3D 類,2D游戲用不上3D相關的東西,無需導入。

          3.將方法里的this用局部變量代替

          當我們的AS3代碼轉成JS后,類中的屬性名在方法中的訪問形式,是會在其前面加上this. 這里的this我們是否能減少呢?如下圖所示:

          上面的方法里有若干個this。如果把this用一個局部分變量來代替,那就是下面的方法這樣。這里的局部變量用的是一個字符的變量,因為最后我們項目會用UglifyJS來壓,所有方法內定義的變量,只要不超過54個,都會是單字符的變量。我們看優化前,一共是有四個this,他們占用16個字符。優化后,四個this變成了四個n,是4個字符,還多出一個賦值語句,這個語句包括中間的空格,包手后邊的分號,一共是11個字符,加上四個n就是15個字符,比優化前少了一個字符。如果這個方法里我再加一個this,那優化前的代碼,就要增加4個字符,而優化后的代碼只需要增加1個字符,所以方法里的this越多,能減少的大小也越多。因此:

          總結來說就是只要方法里的this關鍵字多于3個,就能省字符數量。而且this越多,省得也就越多。我在編譯好的JS代碼里搜索,一共是有近18號個this,這個就可以省很多了。但這個優化要注意,每個function都是一個作用域,每個作用域里的this指代都是不一樣的,所以每個不同的作用域里的this要分別進行計算,也就是說,方法里如果有一個函數,那在計算方法里的this數量時,不應該計算函數里出現的this。第二個,是有一些方法,已經寫了內部的變量賦值是this的,那就可以利用這個已經存在的變量,可以進一步減少字符。這個優化最終省了0.3M。這個優化優化的不僅僅是代碼的大小,因為在JS里,局部變量的調用效率是比this要高的,所以這還可以加快游戲的運行效率。

          4.壓縮包名、類名、方法名、屬性名

          這一步做的事,是把UglifyJS默認不壓的名稱,我們用我們的方式把他給壓了。

          ① 相同的名稱壓為相同的短名稱,把代碼里出現的相同的名稱,壓為相同的短名稱。

          ② obj.abc 與 obj[“abc”] 區別處理:

          默認壓縮規則:obj.abc 寫法的屬性名會被壓縮,obj[“abc”] 寫法的字符串部分不會被壓縮。

          想到這種方式,主要是因為UglifyJS也考慮到有些屬性名壓縮后,可能會引起某些屬性訪問不到,UglifyJS的做法是提供個不壓的屬性名的配置列表,但是這僅僅是個配置列表,我們通過這個列表無法定位到代碼里有用到這些屬性名的地方,有一定的局限性,因此,通過obj.abc 與 obj[“abc”] 區別處理,我們可以在寫代碼的時候就用不同的寫法告訴編譯器,這里的屬性名是否要壓。

          有人會有疑問,用obj[“abc”]的寫法,會比obj.abc的寫法多了三個字符。不用擔心,因為在最后用UglifyJS壓縮的時候,會將[]語法轉成.語法的。

          ③ 自定義標簽 /*[ZIP-JSON]*/

          為了不破壞程序員的編程習慣,我們在不得不用字符串的形式去。

          訪問屬性時,想到了下面的解決方案:在字符串前加上一個/*[ZIP-JSON]*/

          如:

          我們常用的緩動類的用法中,上圖的“x”和“y”是屬性名,我們默認情況下字符串是不會被壓縮的。此時我們可以在代碼中加上/*[ZIP-JSON]*/標簽,如:

          這樣,“x”“y”就會被壓縮成對應的名字了。

          通過這些處理,我們的代碼的寫法就會有以下幾種形式:

          形式1:label 這個屬性名,并不會被壓縮,訪問時也用它原名訪問

          形式2:label這個屬性名在定義時就被壓縮了,可以通過也會被壓縮的.語法去訪問

          形式3:label這個屬性名在定義和訪問時都有被壓縮

          當然,/*[ZIP-JSON]*/做為注釋塊,在最后AS3被轉成JS時,UglifyJS會幫我們把注釋塊給清除掉的,不用擔心加了注釋塊反而代碼會大的問題。

          ④ 特別處理

          諸如 hasOwnProperty、propertyIsEnumerable 等方法,以及Layabox 里的 __JS__ 方法。

          方法里傳入的字符串,其實是屬性名稱。因為默認屬性名稱是會被壓縮的,而字符串是不會被壓縮的,所以對這些方法中名字,我們默認進行壓縮。但要壓縮成什么樣的名字呢?

          上面我們講的,是哪些名稱要壓,壓的時候要注意的一些點,那最終這些名稱,要壓成怎么樣呢?當然是壓到越小越好,那最小是多少呢?一個字符是最好的。我們先看看要做名稱,受哪些限制。名稱是可以由字母組成的,字母是區分大小寫的,還可以使用數字,還有下劃線,還有一個比較不常用的$符號,要注意的是,名稱的首字符不能是數字。如果我們把名稱全用單個字符,可以有多少個名稱呢?26個小寫字母,26個大寫字母,10個數字不有用,加兩個符號,就是54個。那雙字符的名稱呢,就有3456個,三個字符就是22萬個。當然這里能用的還會少幾個,為什么呢?因為比如像as,is,if,for這樣的名稱,也是兩個字符三個字符,但他們是關鍵字,名稱不能和關鍵字重名,不過這樣的關鍵字也不多,不多于10個。三個字符可以有22萬個名稱,那是否夠我們使用了呢?

          上圖是《大天使之劍H5》中所用到名稱字數的分布圖,一共有4萬個名稱,那兩個字符的3千多個肯定是不夠的,三個字符的22萬個就完全可以滿足了。而且我們看看這些名稱的長度分別是多少,可以從表里看到,95%以上的名稱是大于三個字符的,那可以優化的空間就比較大了。最終我們項目把名稱都壓縮完后,一共減少了1.9M。在壓縮名稱這里,大部分工作都是用編輯工具去完成的,有一部分是要修改源代碼的,也寫了一個工具去處理,盡量做到用工具去完成,不然要手動去修改,工作量會變得超大。

          上述的五點對《大天使之劍H5》優化過后,結果如圖所示:

          《大天使之劍H5》的代碼由約10M減小到約5.1M的大小。

          ⑤ 一些還未在《大天使之劍H5》中做的可取優化

          • 靜態常量編譯為JS后是把值寫在使用的地方,這不一定是最優的
          • 方法里使用的屬性賦值給局部變量再使用
          • 使用(param)=>{}代替function(param){}
          • 某類只有一個子類時可減少繼承鏈
          • 包結構可以減化

          四、使用分包

          在上述的優化后,《大天使之劍H5》的主代碼還有5.1M,任然需要對這5.1M進行拆分,這5.1M中,有游戲引擎的部分占了0.7M,其他小文件占了0.2M,剩余的主程序還有4.2M,剩余的4.2M可以通過分包處理。

          怎樣分包我們可以在騰訊和layabox的官網上找到詳細的教程,下面是相關鏈接:

          騰訊官網關于分包加載的說明:

          https://developers.weixin.qq.com/minigame/dev/tutorial/base/subpackages.html

          Layabox官網關于微信小游戲分包的示例:

          https://ldc.layabox.com/doc/?nav=zh-js-5-0-6

          關于在layabox下是如何分包的,在這里簡單說一下:

          在項目的根目錄下,創建一個module.def文件,這是一個文本文件,里邊的內容如下,就可以在編譯后,生成主文件的JS和模塊.js兩個文件。如果要分為多個模塊的,就把這個結構寫多個,都定義好模塊名稱和模塊對應的代碼所在的文件夾就可以了。

          看起來是不是很簡單?但我們隨意的指定一個文件夾下的代碼被編譯為一個模塊獨立出去后,在運行時,就會出錯上圖紅色部分的一個報錯。

          出現這個報錯的原因是主文件會先運行,主文件里引用了模塊里的XXX,而運行到這里的時候,模塊還沒有被加載,所以xxx沒有被定義,所以報錯了。

          所以,要做好分模塊前,就需要對項目進行解偶。要解偶的話,那就得知道,我們分到模塊里的是什么功能,這個功能里如果需要和主程序進行交互,就需要設計相應的中轉機制來進行解偶。

          如果項目是新項目,我們可以在一開始設計游戲的時候就做好這部分內容,在功能進行開發中,會知道這個功能是要分出去的模塊,要以怎么樣的開發規則進行開發,就可以做到解偶進而做到分模塊。

          但我們的游戲已經上線快一年了,如果現在才加入這樣的機制相當于我們要對需要放到模塊里的功能進行重構,這樣做工作量大,而且功能還要重新測試,開發周期開,還容易出BUG。后來我想了一個不需要解偶也可能分模塊的辦法。

          我在說我們辦法前,我要說明一點,我這個辦法只是為了解決在小游戲里做到分包小于4M而做的,與分模塊的設計思路是不太一樣的。分模塊的目的是什么呢?是把還沒有使用到的功能放到模塊中去,需要使用到的時候,再去加載對應的模塊。而我的做法,是需要在進游戲前,需要把所有模塊都加載進來,無論模塊的功能是否需要,也不管模塊里到底是什么功能。

          為了說清楚這點,我們先來看看JS的類。JS的類定義在書寫的時候,是否有先后順序?看看這段代碼,這里定義了一個父類,然后再定義了一個子類。這里我們是否能先寫定義一個子類,再寫定義一個父類嗎?大家注意下子類的定義里,是需要將父類的定義傳入的,如果先寫子類的定義,那傳入的父類定義就是一個undefined,里邊在調到到父類定義里的屬性時,就會報錯。所以父類必須要寫在子類前邊。換成分模塊的情況下是怎么樣呢?假設我們現在有兩個文件,先被加載的叫模塊A,后被加載的叫模塊B。模塊A里有一個子類的定義,在模塊B里有其他類的定義,也包括這個模塊A里的子類的父類的定義。在模塊A被加載完成后,運行到子類的定義時,就調用到了他的父類,因為模塊B還未加載,所以必然報錯了。這里我們要怎么避免報錯呢?很簡單,把父類的定義,也放到模塊A里,那就不會報錯了。如果父類還有父類,而且也在模塊B里的,那記得也要把他的父類也拿到模塊A里。

          具體我們是怎么操作把父類也放到模塊A里的呢?我們只需要在調用Laya的編譯器前,把父類的as文件考到模塊A的文件夾里就可以了。父類里的包名什么的,都不需要做修改。要知道包名在AS里雖然是和文件存放的路徑相匹配的,但在用laya編譯時,是不檢測包名是否和路徑匹配的,最終生成到JS里的,是文件里寫的包名,路徑只做為是放到哪個模塊的依據。

          剛才我們講的是父類是在另一個模塊的情況下引起的報錯。除了這個,還有沒有其他情況呢?有的,比如說我們在剛才的模塊A里的類,在未解偶的邏輯里,是肯定有調用到模塊B的類。不過在初始化時,應該不會運行到業務邏輯里,那為什么會報錯呢?我們來看看模塊A里的代碼。

          模塊A里的頭幾行一般是長這個樣子的,第二行,是將Laya引擎里的一些公共方法定義了短名稱的變量,方便在邏輯里調用。第三行開始,就是把這個模塊里引用到的類,都用類的名稱做變量名賦值,這樣就方便在使用的時候,不需要寫包括包名的類名稱。也就是我們直接寫在AS里的代碼,不用做太多修改就可以在變成可運行的JS。要注意到,這幾行代碼,是在這個JS文件初始化的時候就會被運行的。注意看第四行,我們有一個類,假設這個類叫ClassName,這個類是定義在模塊B里的,那這句賦值語句就會因為模塊B還未加載而找不到ClassName的定義,然后報錯。而且這個類之所以出現在這里,就是因為在該模塊的某個類里使用了它。

          這里我們就明白了,寫在類的方法里的代碼,在初始化的時候是不會被運行的,所以寫了模塊B里定義的類也不會在初始化時報錯,被導入的類會被寫到模塊的最開頭,會在初始化時運行到就會報錯。那我們這么處理,所有模塊A里的類,如果import的類是模塊B的類,那就把這個import刪除掉。并且把所有使用這個類的地方,都寫成用這個函數調用的字符串的包括包名的類名。

          好像這樣改,需要改的地方會比較多,而且生成的代碼里,也會有多處長名稱,我改成了這樣,在類里加一個靜態的變量,讓他等于這個函數,那代碼里就不用修改,使用到這個類名的地方,其實調用的是這個定義的靜態變量。而且編譯為JS后,靜態變量的定義會變成get函數來得到這個值也就是在使用的地方才會調用,而不是初始化的時候。這樣就解決了模塊A的代碼里調用到模塊B的類的引起在初始化的時候報錯的問題。

          做好剛才的兩個地方就完成了嗎?我們再回想一下兩個情況,都是模塊A里的類,如果引用了模塊B里的類,那就想辦法把他的引用去掉,讓他在首次運行時才調用。也就是說,在編譯為JS的時間,模塊A里的類是被當成沒有引用模塊B里的那個類了,那如果模塊B里的那個類,假設叫SimgleClass,只有唯一的一個引用就是模塊A里的類引用了,現在把模塊A里的引用去掉了,那SimgleClass就沒有類引用到它了,也就是編譯的時候,會把這個類不編譯到JS里去。那運行的時候就會因為找不到定義而報錯。所以要在SimageClass里加上強制編譯的標簽,這個是由LayaBox提供的標簽,當有這個標簽時,這個類就算沒有引用,也會被編譯到JS里去。

          最終的結果,如圖所示:

          這4.2M的主程序文件,就被拆分為了一個1.2M和一個3M,小的那個和引擎代碼還有其他一堆小文件一起打包成一個包,共2.1M,3M的那個文件就一個包。在程序運行的時候,會在進入游戲的時候,先加載2.1M的包,完成后會立即加載3M的包。兩個包都加載完成后,才會進入游戲。

          陳源:游戲性能優化

          游戲性能問題,往往是我們游戲程序員最關心的問題,對于這個問題,我在這里總結一下我關于游戲性能優化的八個理念:

          理念一:善于從問題的表象上出發進行優化

          游戲出現問題時,最直接的表現就是卡,造成卡頓的問題又有很多不同的情況。在解決卡頓問題前,我們應該最先排除是否是外部問題造成的卡頓,外部問題:網絡差,硬件差,系統問題等。排除是外部問題導致的卡后,我們可以根據卡頓的現象來定位問題。

          1.輕微的較頻繁卡頓

          1)幀率

          根據游戲自身來設定幀率范圍,一般游戲建議30幀就夠了

          2)Drawcall

          在了解什么是drawcall后,我們知道,過高的drawcall會導致卡頓,這里就介紹一些減少drawcall的方法:

          A.查看drawcall

          在layabox中,添加代碼DebugTool.showStatu=true;

          B.連續渲染相同圖集里的圖,只會執行一次drawcall

          C.UI上drawcall優化

          優化的思路就是盡可能讓相同圖集里的圖一次性連續渲染完,舉例來說:在layabox中打開一個UI,層級窗體里看到界面里的子對象,如下圖:

          我們可以看到看每一個子對象前邊,都有一個小圓點,這個圓點的顏色代表了他來自哪個圖集,相同顏色的圓點代表是同一個圖集。渲染UI時,UI上的每個子對象是按照自上而下的順序去渲染的。在不影響界面的情況下,把界面里各元件的層級調整一下,可以達到減少drawcall的目的。調整后,如圖所示:

          優化前:會有6次drawcall

          優化后:只有3次drawcall

          D.場景上的drawcall優化

          拿場景中的人物來舉例:

          假設一個人物的某套裝資源在一個圖集里。

          那么場景里連續渲染穿這個套裝的人物,只用1次drawcall。實際上在游戲里,穿著相同套裝的人不會理想的按順序出現。一個場景里會有許多穿著不同套裝的人物,而每個套裝在一個圖集。也就是說,場景里,渲染N個這樣的人物就需要無限接近于N次drawcall。

          當每個人物還有影子,影子的資源,肯定是在不同于各個套裝資源的圖集里。

          情況1:人物和影子是在同一個容器里處理,每一個容器就是一個人物,這種情況就會出現,渲染單位A,會使用兩個圖集套裝圖集+影子圖集有兩次drawcall。當渲染N個人物,就有N*2次drawcall。

          情況2:把渲染影子拆出來,當渲染完所有人物后,再根據所有人物的位置,繪制影子。這種情況,渲染N個人物,只會有N+1次drawcall顯然情況2的處理方式更優。

          當每個人物還有名字、稱號、血條等等元素,若這些元素是按照上面情況1的處理,那drawcall就有N*M次。把這些元素按照上面情況2的處理,顯然可以減少大量的drawcall。

          E.其他減少drawcall的方法

          如:減少被遮擋的單位渲染

          圖集的控制

          3)有較高消耗運算,特別是enterframe和for循環里面的

          注意代碼邏輯優化,減少算法復雜度

          4)資源加載緩存有問題/資源太零散,造成I/O過高

          優化資源加載策略

          5)日志打印

          減少日志打印

          6)限制底層繪制分辨率

          2.突然大卡頓

          • 某些不定時的操作,循環里復雜度高

          可能是執行到一些復雜度高的循環處,導致突然大卡頓

          • 協議包過大

          注意協議包優化,優化方式諸如:

          1.刪除不用字段

          2.整合小字段

          如某協議中的字段

          var a:int;

          var b:int;

          var c:int;

          假如上述a,b,c的值只會是十位數以下時,可以整合成一個字段:

          var d:int;

          d的每一位為ABCDEF

          AB為a的值,CD為b的值,EF為c的值

          比如d=123456

          那么a為12,b為34,c為56

          這樣做的好處,原來需要12個字節的數據,現在只用4個字節就可以了。

          3.字段類型選擇

          如用int還是short

          只有兩個值的情況選擇用boolean

          4.盡量避免使用字符串

          協議中的字符串,盡量通過ID發送

          ID對應的字符串在代碼里做好映射或配置

          • 垃圾回收負荷過重

          單位是否是頻繁初始化,用完后就銷毀?

          是否需要使用對象池

          如果卡頓發生UI上:

          • 面板內容初始化分幀處理
          • 圖片和特效尺寸,圖集依賴規劃是否合理
          • UI面板是否分頁簽
          • UI內特效,3D模型等次要元素延遲初始化
          • List優化,動態初始化,循環使用

          3.持續地越來越嚴重卡頓

          • 是否有對象/物件用完了隱藏掉,而沒有被刪除,越積越多

          如:飄血、事件監聽等

          • 內存泄漏,GC越來越頻繁

          4.卡頓到閃退

          • 內存過高,內存有泄漏
          • 檢測是否有報錯或死循環等問題

          理念二:內存為主

          很多能感知的較大卡頓都是垃圾回收引起的;

          內存問題往往比CPU問題更難解決,甚至需要大規模重構;

          降低內存會使得游戲更加輕快,可以緩解其他較小問題。

          理念三:內存使用策略比內存釋放策略更重要

          關于內存使用的策略,往往在項目的初期就應該制定好,下面有幾點建議:

          • new對象必須由Factory或者Manager進行統一管理,這點做好了,對后期排查內存問題尤為重要;
          • View和Model要完全分離;
          • View的創建細化到每幀,根據性能情況創建;
          • FpsManager按照幀率動態調整閥值;
          • 合理地運用對象池:“頻繁創建和銷毀”的“小型”對象采用對象池。

          理念四:重視資源壓縮

          游戲程序中,大量的內存來自于資源,合理的壓縮資源是減小內存行之有效的辦法。關于資源壓縮,這里提一些建議:

          • 重視制定制作流程,技術標準

          資源的制作不能隨心所欲,必須擁有一定的標準,例如:

          1. 原始圖片資源使用jpg還是png
          2. 是否是可以用鏡像處理的圖片資源
          3. 相似的資源是否可以統一
          4. 避免程序上使用濾鏡和灰化等
          5. 一些圖片資源上不起眼的光效或羽化效果等是否可以不用
          6. 美術字體圖片中,相同文字的拆分與組合
          7. 九宮格拉伸圖片的概念
          • 合理優化動作、特效等資源序列幀

          許多人物動作、特效等資源,美術給出的效果十分精細。在處理內存問題上,可以考慮對這些資源做如下處理:

          1.抽幀

          一些影響不大的關鍵幀是否可以刪除。

          2.縮小再放大

          一些不起眼的部位,序列幀可以按比例縮小,程序使用時,再放大。

          3.砍方向

          人物向左和向右的資源是否可以通過旋轉其中一個動作實現?

          是否所有方向的資源都要用到?

          • 對稱的資源砍半/四分之一鏡像使用
          • 序列幀特效用IDE制作替代
          • UI全屏分辨率選擇 1024像素
          • icon盡量使用 64*64 的格式
          • 使用pvrtc etc ,png8格式
          • UI背景使用最接近的某個2的次方的尺寸
          • 背景圖不要打到圖集中,并且盡量用jpg
          • 少用遮罩
          • 音效使用單聲道

          理念五:屏蔽策略

          在游戲出現性能瓶頸的時候,我們不得不考慮屏蔽一些游戲內容的顯示,比如一些次要的場景單位、特效等。屏蔽必然會減弱玩家的游戲體驗,但是,比起卡頓甚至是閃退,適當的屏蔽規則是必要的。

          • 加入屏蔽設置,性能差的時候自動開啟
          • 屏蔽策略要覆蓋各類顯示對象
          • 某些場景使用統一模型

          理念六:不要忽略看起來小的地方

          正所謂積少成多,一些看起來小的地方,卻用了不太合理的處理方式,往往也影響著游戲的性能,在《大天使之劍H5》中,我們就對如下這些地方做了些優化:

          • 配置表數據優化
          • String數組方案
          • 相似String的處理
          • 版本號文件,采用樹形存儲減少URL字段的重復度
          • 數值類型廣泛使用變長
          • 解析戰報,分段解析

          理念七:深入學習開發者工具的使用

          在調試游戲時,我們往往要依賴開發者工具來獲悉游戲的內存變化、CPU的使用、游戲內對象的整體情況、資源的應用情況、甚至是我們關注的變量值等等。善于使用各種開發者工具能讓我們事半功倍。

          • 使用谷歌瀏覽器的開發者工具

          layabox開發的H5游戲默認是用谷歌瀏覽器調試的,這里我們稍微講下谷歌瀏覽器的開發者工具的運用。游戲運行在谷歌瀏覽器時,按F12可以打開開發者工具,他的一些常用功能有:

          1.console的使用

          Console的界面如上圖所示,它主要顯示著我們游戲運行時的日志等信息。每條日志的后面,有鏈接可以快速跳轉到輸出日志的代碼處,在console的下方,有輸入框功能,我們可以通過這里輸入代碼改變當前游戲內的數值、用不同方式打印日志等。

          2.調試

          我們可以在工具的Sources選項卡下找到我們要調試的JS,進行斷點或條件斷點調試。

          3.NetWork

          NetWork面板提供了有關已經下載和加載過的資源的詳細信息。

          在這里我們可以很直觀的找到一些加載耗時較長的資源進行優化。

          4.TimeLine

          TimeLine界面中,我們可以看到關于時間開銷的完整概述。

          如圖所示,通常我們在游戲性能表現差的情況下,在TimeLine界面點擊左上角的錄制按鈕,錄制一段時間后,點擊完成,它會幫我們搜集到在錄制的這段時間里,游戲每一幀的運行狀況。

          • 綠色的幀是在幀時間內處理完需求處理的事情的。
          • 紅色的幀是處理時間大于幀應該有的時間的,也就是卡了的幀。

          我們可以重點看下紅的幀,在下邊可以看到是哪個方法占了多少時間,以及這個文件里又是調用哪些方法,分別調多少時間。

          在圖中左下部分,我們還可以看到代碼邏輯和渲染的比重,可以用來判斷可以做什么優化,怎么優化。這個功能,對程序的參考決不止我提到這些,這里有很多信息幫我們分析找到問題,可以對我們優化提供很多幫助。

          5.Profiles

          Profiles界面中,我們可以使用快照功能。最常用的還是Take Heap Snapshot功能。它可以記錄當前內存分布的詳細信息,多張內存快照還可進行比對,分析在不同的時間點,內存具體有哪些變化。

          理念八:抓大放小,先抗住再優化

          沒有一個性能問題是由單一問題造成的;

          單次單點修改,注意記錄便于前后對比找到關鍵問題;

          調試崩潰的時候一定要注重日志,一行一行看總會找到Keyword。

          關于極光會客廳

          “極光會客廳”是由三七互娛極光網絡牽頭組織的線下分享沙龍系列活動,以分享干貨為核心追求,涵蓋技術、美術、策劃、市場等不同維度,為廣大游戲研發人員提供一個相互學習交流的平臺。

          信小游戲是基于微信小程序的一個新增類目,它結合了H5游戲和微信社交的優勢,為開發者提供了一個快速、便捷的開發游戲平臺。北京木奇移動技術有限公司,專業的軟件外包開發公司,歡迎交流合作。

          開發方式

          微信小游戲主要采用以下方式進行開發:

          • 基于HTML5 Canvas: 這是微信小游戲最常用的開發方式,開發者可以使用HTML5 Canvas繪制游戲畫面,并通過JavaScript來實現游戲邏輯。
          • 游戲引擎: 為了提高開發效率,開發者可以使用Cocos Creator、LayaAir等游戲引擎來開發微信小游戲。這些引擎提供了豐富的組件、工具和插件,可以幫助開發者快速構建游戲。
          • 原生插件: 對于一些需要調用微信原生能力的游戲,開發者可以使用原生插件來實現。例如,可以使用原生插件來實現音頻播放、震動、分享等功能。

          特點

          微信小游戲具有以下顯著特點:

          • 即點即玩: 用戶無需下載安裝,直接在微信中點擊即可玩,用戶體驗良好。
          • 社交分享: 小游戲與微信社交體系深度結合,方便用戶分享游戲成績、邀請好友一起玩,擴大游戲傳播范圍。
          • 輕量級: 小游戲對設備性能要求較低,可以在各種配置的手機上流暢運行。
          • 開發便捷: 微信提供了豐富的開發文檔和工具,開發者可以快速上手,降低開發門檻。
          • 性能優異: 微信小游戲引擎對性能進行了優化,可以保證游戲的流暢運行。
          • 微信生態支持: 小游戲可以充分利用微信的支付、登錄、分享等功能,為開發者提供更多的商業化可能。

          開發流程

          一般來說,微信小游戲的開發流程如下:

          1. 注冊小程序賬號: 在微信公眾平臺注冊一個小程序賬號。
          2. 創建小游戲項目: 使用微信開發者工具創建一個新的游戲項目。
          3. 游戲開發: 使用HTML、CSS、JavaScript或游戲引擎開發游戲。
          4. 調試: 在微信開發者工具中進行調試,確保游戲功能正常。
          5. 提交審核: 提交游戲代碼到微信公眾平臺進行審核。
          6. 發布上線: 審核通過后,游戲即可發布上線。

          優勢

          • 降低開發成本: 相比于原生App游戲,微信小游戲的開發成本更低,開發周期更短。
          • 快速推廣: 借助微信龐大的用戶基數,小游戲可以快速獲得大量用戶。
          • 數據分析: 微信提供豐富的數據分析工具,幫助開發者了解用戶行為,優化游戲。

          注意事項

          • 包體積限制: 小游戲對包體積有一定限制,開發者需要對游戲資源進行優化。
          • 性能優化: 為了保證游戲的流暢運行,開發者需要對游戲進行性能優化。
          • 兼容性問題: 由于不同手機設備的差異,開發者需要考慮游戲的兼容性問題。

          總結

          微信小游戲為開發者提供了一個快速、便捷的游戲開發平臺,具有即點即玩、社交分享、輕量級等特點。開發者可以充分利用微信生態的優勢,開發出更多有趣、好玩的小游戲。


          主站蜘蛛池模板: 精品日韩在线视频一区二区三区| 中文字幕一区精品| 一区二区三区免费视频播放器| 亚洲A∨无码一区二区三区| 波多野结衣中文一区二区免费| 好爽毛片一区二区三区四无码三飞| 99精品国产高清一区二区三区 | V一区无码内射国产| 亚洲av无码一区二区乱子伦as| 无码一区18禁3D| 亚洲AV无码一区二区二三区软件 | 国产主播一区二区| 色国产在线视频一区| 无码一区二区三区| 精品久久国产一区二区三区香蕉| 日本不卡一区二区视频a| 亚洲一区二区观看播放| 老熟妇仑乱视频一区二区| 亚洲成av人片一区二区三区| 日韩在线视频一区二区三区| 农村乱人伦一区二区| 无码国产精品一区二区免费3p| 国产一区二区三区免费在线观看| 日本不卡一区二区视频a| 亚洲一区二区三区无码中文字幕| 国产一区二区福利久久| 国产SUV精品一区二区88L| 日韩色视频一区二区三区亚洲| 精品国产一区二区三区久| 在线精品日韩一区二区三区| 成人国产精品一区二区网站| 亚洲国产成人久久综合一区77 | 91精品福利一区二区三区野战| 亚洲视频在线观看一区| 亚洲老妈激情一区二区三区| 国产精品免费一区二区三区四区| 国产色情一区二区三区在线播放| 人妻少妇一区二区三区| 人妻无码第一区二区三区| 中文字幕无码不卡一区二区三区| 国内精品视频一区二区三区|