盡管谷歌在前不久表示Google Play的應(yīng)用大小從50MB提高到了100MB,但對于碎片化嚴(yán)重的Android平臺來說,一款游戲想要適配多種屏幕尺寸仍然需要考慮包體的問題。最近一名安卓游戲開發(fā)者在博客中講述了自己把游戲包體從106M降低到12M所用到的方法,遇到同樣問題的童鞋們不妨借鑒。
在分析了各種安卓設(shè)備的不同分辨率之后,我決定把所有的游戲資源都用6種不同的尺寸來做。然而,我擔(dān)心這樣做會增加最終游戲的apk文件大小,所以,我首次開始做這款游戲的時候就決定檢查所有的資源。
我創(chuàng)造了一個只包含最低(800×480)和最高(2560×1600)分辨率圖片的包體,大小是106M!
我需要增加4種其他大小的分辨率,所以我推測最終的apk大小至少在300MB以上,我搜索了文檔,然后發(fā)現(xiàn)谷歌的要求包體是100MB以下,其他必須通過分割資源包的形式下載。要不然,你也可以為不同的設(shè)備提供不同的apk文件,但這兩種做法我都不太喜歡,我最討厭下在安卓游戲之后還必須等待更多的時間下載數(shù)百兆資源,我需要新的方式解決這種沖突。
我上網(wǎng)進(jìn)行了搜索,大多數(shù)的建議是把你的代碼用壓縮器或者模糊處理(obfuscator programs)軟件打包,但得到的效果其實是可以忽略不計的。隨后,一個建議引起了我的注意,那就是把圖片格式全部使用JPEG。我使用TextureAtlas自動打包所有資源,但我可以把這些圖片和沒有透明區(qū)域的地方分隔開,然后把它們作為PNG或者JPG圖片集分別打包。
然而問題是,我游戲當(dāng)中90%的圖片都是需要透明度的,在這種情況下我們最主要的問題就是卡牌圖片,這些圖片都有圓角。隨后我想到了這個想法:把這些卡牌圖片分為框架和內(nèi)容,這款游戲中只有4種卡牌類型,所有同類的卡牌都有相同的框架??ㄅ苾?nèi)部每一個都是不同的,但這些內(nèi)容都不要求透明度。我并沒有把126張卡片打包成PNG圖片,而是全部做成了JPG圖片,外加4張PNG框架圖。
在分步處理圖片的時候,確保JPG圖片首先被畫出來,PNG框架覆蓋其上。順便提一句,我說的分步處理指的是把圖形放到libGDXStage(Group)當(dāng)中。為了讓代碼更簡單,我創(chuàng)作了Cardimage類(class)來處理透明化的繪圖,這個Group包含來自JPG圖片的卡牌中心,然后把來自PNG圖片的框架覆蓋其上。
這節(jié)約了大量的空間,但我還擔(dān)心在做翻轉(zhuǎn)動作的時候?qū)е掳w過大。當(dāng)卡牌面向左邊或者右邊的時候,我會直接把這張圖翻過來,這樣就會節(jié)約空間,因為我不必存儲完整的卡牌圖像。我嘗試過能否只翻轉(zhuǎn)一部分圖像,這可能要使用AtlasRegion.flip()函數(shù),但我不想翻轉(zhuǎn)完整的JPG圖像,這些圖片部分應(yīng)該保持相同,而且只有完整的圖形才需要展示出來,為此,在calling flip(true,false)之后,我使用了setRegionY和setRegionHeight縮減翻轉(zhuǎn)區(qū)域的大小,通過使用翻轉(zhuǎn)區(qū)域,我創(chuàng)造了另一個圖形而且把它加入到了CardImaeg group里,在運行的時候,我只需要簡單地展示或者隱藏這個圖片就可以了。
結(jié)果,新方法創(chuàng)作出來的apk文件在包含了同樣內(nèi)容的情況下,大小降到了12MB,也就是說這個處理節(jié)約了88%的空間。加入了其他四種分辨率之后,apk包體降到了42MB,和此前預(yù)計的300MB相差9倍多。
總結(jié)
除了你能夠在網(wǎng)上找到的所有其他建議之外,比如壓縮代碼等等,還需要增加以下三條:
1.在可能的情況下盡量使用JPG格式的圖片;
2.如果你使用PNG只是為了半透明邊框,最好是把圖片剪裁成邊框+內(nèi)容的方式,把框架用PNG存儲,內(nèi)容用JPG存儲。或者,還可以用更換高的方式:把邊框建材城四部分(左右上下),然后在運行的時候把它們組合起來,不要在PNG框架中增加更多的空間,這樣不僅可以節(jié)約存儲量,還可以使用更少的圖片,所以游戲運行會更快。
3.如果你的圖片需要翻轉(zhuǎn)或者旋轉(zhuǎn),那么你只需要存儲初始版本,然后在運行的時候進(jìn)行翻轉(zhuǎn)或者旋轉(zhuǎn)即可。