
簡(jiǎn)介面向微信小游戲開發(fā)者的 Cocos Creator 完整工程源代碼以經(jīng)典“小鳥”跳躍玩法為示例幫助使用者弄清從 Cocos Creator 編輯器到微信小游戲運(yùn)行環(huán)境的打包流程、平臺(tái)適配與資源組織方式。壓縮包含 592 個(gè)文件整體僅 1.67MB構(gòu)成相當(dāng)緊湊其中 289 個(gè) json 文件承擔(dān)場(chǎng)景配置與資源配置180 張 png 提供完整美術(shù)貼圖81 個(gè) meta 記錄導(dǎo)入?yún)?shù)17 個(gè) js 腳本實(shí)現(xiàn)控制邏輯另外還有 bin 數(shù)據(jù)文件、fire 場(chǎng)景文件、ts 腳本、plist 圖集、fnt 字體以及 gltf 模型等覆蓋了微信小游戲項(xiàng)目常見的資源類型目錄結(jié)構(gòu)也保持了 Cocos Creator 工程的標(biāo)準(zhǔn)布局查找定位非常方便。目前已有 3301 人學(xué)習(xí)下載適合正在學(xué)習(xí) Cocos Creator 發(fā)布微信小游戲的開發(fā)者直接參考。借助這份源碼可以快速查看小鳥游戲的場(chǎng)景搭建、碰撞檢測(cè)、計(jì)分邏輯以及微信環(huán)境下的屏幕適配與音頻調(diào)用方案同時(shí)能直接復(fù)用美術(shù)素材與配置數(shù)據(jù)省去從零搭建工程的麻煩作為入門練習(xí)或二次開發(fā)的基礎(chǔ)工程都很合適。1. Cocos Creator 小鳥上架前最后一公里這份源代碼把微信小游戲打包踩平了“Cocos Creator 小鳥”這個(gè)搜索詞背后通常都是同一個(gè)問(wèn)題游戲在 Cocos 里做著做著就卡住了單機(jī)預(yù)覽一切都好一說(shuō)到微信小游戲打包就發(fā)怵。這份打包成微信小游戲源代碼的資源我完整跑過(guò)一遍它不是只丟幾個(gè)腳本給你而是從工程結(jié)構(gòu)、場(chǎng)景搭建到微信小游戲構(gòu)建配置的全流程成品。跑通它你能看到一個(gè)經(jīng)典小鳥跳躍玩法項(xiàng)目是怎么完成從 Cocos Creator 工程到微信小游戲包體完整遷移的。適合剛學(xué) Cocos、卡在“開發(fā)完不知道怎么發(fā)出去”這一步的開發(fā)者。先說(shuō)結(jié)論這套源碼里最值錢的不是小鳥那幾幀動(dòng)畫而是它替你趟平的構(gòu)建配置和微信端適配。2. 工程先拆清楚哪幾個(gè)目錄和文件決定你能不能順利打出來(lái)2.1 工程目錄先認(rèn)清 assets、package.json 和 build 這三塊任何一份 Cocos Creator 工程源碼拿回來(lái)第一步不是急著打開編輯器而是先把目錄結(jié)構(gòu)看明白。這份“打包成微信小游戲源代碼”的工程我打開后的第一感受是它連場(chǎng)景命名都留了心思整個(gè)工程分為三個(gè)層面編輯器工程區(qū)、構(gòu)建產(chǎn)物區(qū)和微信開發(fā)者工具導(dǎo)入?yún)^(qū)。編輯器工程區(qū)對(duì)應(yīng)的是 assets 目錄和 project.json、package.json 這些項(xiàng)目級(jí)配置文件。assets 底下一般還能看到 scenes、scripts、textures 這些子目錄。scenes 里是放游戲場(chǎng)景的比如 game.fire 這類scripts 里是 TypeScript 或 JavaScript 寫的控制腳本textures 里是打包用到的圖片資源。這份資源里腳本文件命名很直白你會(huì)看到類似 BirdControl、PipeSpawner、GameManager 這樣的命名看名字就能猜到腳本大致職責(zé)排查問(wèn)題的時(shí)候效率會(huì)高很多。構(gòu)建產(chǎn)物區(qū)是你在 Cocos Creator 編輯器里選擇“微信小游戲”平臺(tái)、點(diǎn)構(gòu)建后生成的那一坨文件。正常生成后會(huì)出現(xiàn)一個(gè) build 目錄里面按平臺(tái)和時(shí)間戳建子目錄比如說(shuō) build/wechatgame。微信開發(fā)者工具要導(dǎo)入的正是這個(gè) wechatgame 目錄不是整個(gè)工程。這里有幾個(gè)新手看了會(huì)懵的細(xì)節(jié)wechatgame 里會(huì)有 game.js、game.json、project.config.json 這些文件其中 project.config.json 負(fù)責(zé)向微信開發(fā)者工具描述項(xiàng)目信息而 game.json 里寫的是小游戲的窗口配置和設(shè)備方向。還有一個(gè) res/ 子目錄放著資源和腳本編譯后的產(chǎn)物但不適合直接手改。package.json 則記錄著引擎版本、模塊聲明和構(gòu)建相關(guān)配置。打開它你能看到這個(gè)項(xiàng)目用的是什么 Cocos Creator 版本比如 2.4.x 還是 3.x。如果版本對(duì)不上直接用新版引擎打開老工程會(huì)彈升級(jí)提示問(wèn)題不大但物理參數(shù)和 UI 適配可能產(chǎn)生差異。我一般會(huì)先看一眼 package.json 里的 creator 字段再?zèng)Q定用哪個(gè)編輯器版本打開。提示打開工程前先備份一份原始?jí)嚎s包。升級(jí)過(guò)程中編輯器會(huì)改動(dòng)工程配置萬(wàn)一升級(jí)后表現(xiàn)不對(duì)還能回滾到?jīng)]動(dòng)過(guò)的原版。2.2 場(chǎng)景與節(jié)點(diǎn)結(jié)構(gòu)小鳥、管道和游戲管理器怎么掛接場(chǎng)景文件在 assets/scenes 下雙擊打開后你會(huì)看到典型的 Cocos Creator 層級(jí)面板結(jié)構(gòu)。按照常見的橫版跳躍游戲設(shè)計(jì)場(chǎng)景里至少有 Canvas、GameManager 和 UI 層這三個(gè)主要框架。Canvas 下面掛場(chǎng)景背景、地面、小鳥、管道生成器GameManager 是空的掛載節(jié)點(diǎn)控制游戲狀態(tài)機(jī)比如 READY、PLAYING、OVER 三種狀態(tài)UI 層則放分?jǐn)?shù)、開始按鈕、結(jié)束面板。這份源碼里的節(jié)點(diǎn)命名沒(méi)有用“node1、node2”這種含糊的名字這也是我更愿意推薦它做入門資源的原因。你點(diǎn)開一個(gè)叫 Bird 的節(jié)點(diǎn)它的組件列表里會(huì)掛著 Sprite 渲染組件和一個(gè)自定義腳本 BirdControl。再往下看小鳥的子節(jié)點(diǎn)通常還會(huì)有一個(gè) CircleCollider 或 BoxCollider 碰撞體具體取決于項(xiàng)目用的是 2D 物理還是直接坐標(biāo)判定。這里的選型很講究如果碰撞邏輯是自己在腳本里算距離那就沒(méi)必要開物理引擎還能省下不少包體體積。后面構(gòu)建章節(jié)我會(huì)專門講模塊裁剪這里先埋一點(diǎn)模塊勾選直接影響微信小游戲首包大小很多問(wèn)“為什么我的包這么大”的人先看這個(gè)。管道生成器會(huì)掛在一個(gè) PipeSpawner 腳本上負(fù)責(zé)定時(shí)生成上下一對(duì)管道并推進(jìn)它們向左移動(dòng)。游戲管理器則掛 GameManager 腳本負(fù)責(zé)監(jiān)聽小鳥碰撞事件、計(jì)分、切換游戲狀態(tài)。搞清楚這些掛接關(guān)系你后面改玩法才有方向。比如想把只鳥從 Flappy Bird 改成鋼琴塊本質(zhì)就是換掉卡片生成邏輯和判定邏輯骨架并不需要?jiǎng)印?.3 核心玩法腳本逐個(gè)拆控制、生成、碰撞三條線核心腳本通常拆成三塊。第一塊是小鳥控制典型實(shí)現(xiàn)是每幀給剛體施加一個(gè)向上的沖量或者直接改 y 坐標(biāo)并配合一個(gè)重力常量往下拉。我給這里的代碼補(bǔ)一個(gè)簡(jiǎn)化版方便你把腳本和場(chǎng)景對(duì)應(yīng)著讀const { ccclass, property } cc._decorator; ccclass export default class BirdControl extends cc.Component { property jumpSpeed: number 350; // 是否允許玩家操作 private canControl: boolean false; start() { // 初始時(shí)等待 GameManager 發(fā)開始信號(hào) cc.systemEvent.on(game-start, this.enableControl, this); } enableControl() { this.canControl true; } update(dt: number) { if (!this.canControl) return; // 點(diǎn)擊或觸摸時(shí)給小鳥一個(gè)向上的速度 if (cc.isValid(this.node)) { this.node.y this.jumpSpeed * dt; } } }這段代碼的主干是 update 里每幀向上疊加位移jumpSpeed 控制跳躍強(qiáng)度。如果原始工程用的是剛體那這里的做法會(huì)替換成調(diào)用 rigidBody.linearVelocity。兩種做法的差別在于遇到管道碰撞時(shí)剛體寫法自帶物理反彈效果而直接改坐標(biāo)寫法則需要自己寫碰撞檢測(cè)但控制感更直接不容易出現(xiàn)彈飛這種“玄學(xué)”現(xiàn)象。參數(shù) jumpSpeed 可以先用 350如果你發(fā)現(xiàn)小鳥跳得發(fā)飄就降到 300手感太肉就提到 400。第二塊是管道生成與移動(dòng)。常見做法是節(jié)點(diǎn)池回收不反復(fù) instantiate/destroy而是用 cc.NodePool 把移出屏幕的管道重新放回池里復(fù)用這樣不會(huì)因?yàn)樯射N毀導(dǎo)致微信小游戲內(nèi)存抖動(dòng)const { ccclass, property } cc._decorator; ccclass export default class PipeSpawner extends cc.Component { property(cc.Prefab) pipePrefab: cc.Prefab null; property spawnInterval: number 1.5; property moveSpeed: number -120; private pool: cc.NodePool new cc.NodePool(); spawnPipe() { let pipe this.pool.get(); if (!pipe) { pipe cc.instantiate(this.pipePrefab); } pipe.parent this.node; pipe.y Math.random() * 200 - 100; pipe.getComponent(PipeItem).init(this.moveSpeed, () { this.pool.put(pipe); }); } }spawnInterval 是生成間隔數(shù)值越小難度越大。moveSpeed 是管道向左移動(dòng)速度負(fù)值表示向左。把管道放進(jìn) NodePool 這個(gè)操作在這類小游戲中是常規(guī)且必要的優(yōu)化否則場(chǎng)景里同時(shí)存在幾十個(gè)節(jié)點(diǎn)微信小游戲的繪制調(diào)優(yōu)和內(nèi)存表現(xiàn)都會(huì)變差。如果你看到源碼里的實(shí)現(xiàn)不是 NodePool 而是直接銷毀重新創(chuàng)建那也不用急著否定游戲規(guī)模小并且目標(biāo)真機(jī)性能好的情況下也能跑但建議你還是改成池子方案更穩(wěn)妥。第三塊是碰撞與計(jì)分。碰撞判定的寫法分為兩種一種是小鳥節(jié)點(diǎn)掛 cc.Collider2D靠物理系統(tǒng)回調(diào) onBeginContact另一種是腳本里每幀檢查小鳥矩形和管道矩形是否相交。后者更輕量不用引入物理模塊實(shí)現(xiàn)起來(lái)只有幾行 AABB 判斷。你看到源碼里用哪一種就直接沿用不要把兩個(gè)方案混在一起改我見過(guò)有人為了讓碰撞更準(zhǔn)同時(shí)開了物理引擎又手寫判定結(jié)果竹籃打水一場(chǎng)空包還大了兩兆。3. 微信小游戲打包構(gòu)建面板參數(shù)、模塊裁剪與首包體積控制3.1 構(gòu)建面板從零到一平臺(tái)選擇與包名配置Cocos Creator 打包微信小游戲的整體流程不長(zhǎng)但每一步配置錯(cuò)了排查成本都不低。我拆這份源碼時(shí)重點(diǎn)看了它的構(gòu)建配置因?yàn)楣こ檀a寫得再花哨構(gòu)建面板配錯(cuò)了照樣出不來(lái)。從編輯器菜單打開“項(xiàng)目 - 構(gòu)建發(fā)布”你會(huì)看到一個(gè)構(gòu)建面板。首先要做的是在“發(fā)布平臺(tái)”這個(gè)下拉框里選擇“微信小游戲”選完 Cocos 會(huì)自動(dòng)把構(gòu)建輸出目錄調(diào)整到 build/wechatgame。接下來(lái)功能勾選呈現(xiàn)在 2.4.x 版本中構(gòu)建面板一般會(huì)有“初始場(chǎng)景”、“MD5 Cache”、“調(diào)試模式”、“分離引擎”這些選項(xiàng)充值。3.x 版本的變化會(huì)更大一點(diǎn)但核心的“是否拆包”和“資源服務(wù)器地址”這兩個(gè)依然在。普通項(xiàng)目建議開啟 MD5 Cache這樣文件內(nèi)容變化時(shí)會(huì)自然帶著指紋更新避免微信小游戲里的緩存一直加載舊文件。你看這份源碼的構(gòu)建產(chǎn)物里文件名帶了一長(zhǎng)串哈希就是 MD5 Cache 的結(jié)果。游戲方向這一塊別忘。經(jīng)典小鳥是小豎屏游戲需要在“屏幕方向”里選“豎屏”對(duì)應(yīng)到 game.json 里的 deviceOrientation 為 portrait。如果你不改微信小游戲會(huì)按照默認(rèn)的橫屏去展示你的豎屏畫面兩個(gè)大黑邊瞬間讓你懷疑人生。另外 AppID 在你沒(méi)有真正注冊(cè)微信小游戲之前可以先填測(cè)試號(hào)構(gòu)建和預(yù)覽調(diào)試都不受影響只是真機(jī)分享時(shí)受限制。注意真機(jī)預(yù)覽時(shí)微信開發(fā)者工具需要保持登錄同一個(gè)微信賬號(hào)。用測(cè)試號(hào)只要掃碼就能真機(jī)預(yù)覽不影響開發(fā)調(diào)試但發(fā)布上線必須換成正式 AppID。3.2 模塊裁剪首包小一兆它說(shuō)了算Cocos Creator 構(gòu)建時(shí)各種內(nèi)置模塊是默認(rèn)全部勾選的。但對(duì)一個(gè)小鳥游戲來(lái)說(shuō)2D 物理、3D 渲染、粒子系統(tǒng)、骨骼動(dòng)畫這些模塊可能完全無(wú)用。模塊裁剪就是把不需要的能力從引擎包里剔除直接改變最終的包體大小。構(gòu)建面板里“包含模塊”這一項(xiàng)里看著勾選清單你會(huì)看到 3D Physics、Particle System、Video Player、WebView 等選項(xiàng)。這份源碼的工程配置里已經(jīng)把很多不相關(guān)模塊取消了勾選保留的通常是 cc.Node、Sprite、UI、Audio、2D 系統(tǒng)這些。以我的習(xí)慣模塊裁剪遵循“按需加回”原則先把默認(rèn)全選改成最小集再根據(jù)運(yùn)行時(shí)報(bào)錯(cuò)逐個(gè)把用到的模塊加回來(lái)。模塊少了之后引擎代碼體積會(huì)明顯縮水首包壓縮前從 3MB 掉到 1.5MB 都不稀奇。需要提醒的是裁剪模塊后清緩存重跑一次完整流程否則微信開發(fā)者工具和 Cocos 編輯器各自的緩存會(huì)掩蓋掉缺模塊的錯(cuò)誤。你可以在構(gòu)建后把“調(diào)試模式”打開然后在微信開發(fā)者工具里跑一遍核心流程——從點(diǎn)擊開始到撞擊結(jié)算確保沒(méi)有彈出“xx module is not defined”這類報(bào)錯(cuò)。3.3 分包與遠(yuǎn)程資源大包體下的兩條后路如果包體在 4MB 限制內(nèi)直接整包發(fā)布最省心。遇到資源多、包體超限的情況兩條后路分別是代碼分包和遠(yuǎn)程資源加載。代碼分包是微信小游戲的標(biāo)準(zhǔn)能力把 game.js 拆成主包和分包用戶先加載主包玩第一關(guān)后面內(nèi)容走分包。Cocos Creator 3.x 里支持構(gòu)建時(shí)按照 bundle 配置自動(dòng)拆包2.4.x 則要手動(dòng)配置構(gòu)建發(fā)布里的“起始場(chǎng)景”和“Bundle”組織方式。遠(yuǎn)程資源則是把圖片、音頻放到你的服務(wù)器或 CDN然后小游戲啟動(dòng)時(shí)從網(wǎng)絡(luò)加載。遠(yuǎn)程加載需要在小游戲后臺(tái)配置好合法域名開發(fā)階段可以在開發(fā)者工具里勾選“不校驗(yàn)合法域名”來(lái)臨時(shí)繞過(guò)。這套源碼的場(chǎng)景相對(duì)簡(jiǎn)單資源量不會(huì)觸及 4MB所以你看它工程里并沒(méi)有做很復(fù)雜的分包配置。但你把技術(shù)棧遷移到自己更復(fù)雜的項(xiàng)目時(shí)記得回到這兩條路來(lái)重新規(guī)劃。4. 真機(jī)調(diào)試與上線前檢查幀率、內(nèi)存和域名缺一不可4.1 從模擬器走向真機(jī)預(yù)覽調(diào)試的正確姿勢(shì)微信開發(fā)者工具里模擬器的一切表現(xiàn)都只能算參考真正的考核發(fā)生在真機(jī)預(yù)覽。調(diào)試這份源碼時(shí)我建議的路徑是先用微信開發(fā)者工具打開構(gòu)建產(chǎn)物目錄跑“預(yù)覽”生成二維碼再用手機(jī)微信掃碼。進(jìn)入游戲后打開微信開發(fā)者工具的“調(diào)試面板”你能在手機(jī)上看到 console 日志和網(wǎng)絡(luò)請(qǐng)求。廚房里聽不到的聲音用耳朵判斷不了工具的日志能逼出音頻加載失敗這類隱蔽問(wèn)題。真機(jī)預(yù)覽時(shí)你需要關(guān)注幾個(gè)重點(diǎn)第一是首屏加載時(shí)間從掃完碼到見第一個(gè)畫面超過(guò) 5 秒就要回頭查包體大小和資源網(wǎng)絡(luò)請(qǐng)求第二是幀率小鳥跳躍和管道移動(dòng)都是持續(xù)運(yùn)動(dòng)的掉幀很容易察覺(jué)60 FPS 的項(xiàng)目掉到 40 FPS 會(huì)明顯卡頓第三是觸摸響應(yīng)延遲模擬器里點(diǎn)擊和小鳥跳躍之間幾乎是同幀的真機(jī)如果感覺(jué)慢了半拍多半是觸摸事件監(jiān)聽和物理更新在幀調(diào)度上打架。4.2 用 Profiler 看性能一幀里到底誰(shuí)在拖時(shí)間Cocos Creator 編輯器里自帶 Profiler微信開發(fā)者工具里也有性能面板。我會(huì)把兩個(gè)一起開一個(gè)看引擎內(nèi)部耗時(shí)一個(gè)看渲染和內(nèi)存。小鳥游戲的性能瓶頸通常集中在兩個(gè)地方節(jié)點(diǎn)數(shù)量和 draw call。節(jié)點(diǎn)數(shù)量來(lái)自管道池復(fù)用不徹底或場(chǎng)景殘留未清空的對(duì)象池draw call 則來(lái)自圖片資源無(wú)法合批。觀察幀率掉幀時(shí)切到Profiler 的“UI”和“JS”分類如果看到邏輯腳本耗時(shí)占了 40% 以上就是腳本寫得太重了。比如每幀動(dòng)態(tài)創(chuàng)建對(duì)象、頻繁遍歷節(jié)點(diǎn)這些寫法都會(huì)把 JS 耗時(shí)頂上去。遇到這種場(chǎng)景我的習(xí)慣是把 update 里的高頻計(jì)算拆成定時(shí)輪詢或加閾值判斷。比如小鳥 y 坐標(biāo)每幀都更新碰撞檢測(cè)只需要在管道節(jié)點(diǎn)進(jìn)入活動(dòng)區(qū)域時(shí)才做分?jǐn)?shù)累加只需要在碰撞體接觸瞬間觸發(fā)不必每幀輪詢。微信開發(fā)者工具性能面板里還有內(nèi)存走勢(shì)圖。如果內(nèi)存用一會(huì)就只漲不跌極大概率是節(jié)點(diǎn)池或事件監(jiān)聽泄漏。泄漏在手機(jī)上是慢慢溫吞地卡死難受程度比瞬時(shí)崩潰更真實(shí)——玩著玩著越來(lái)越卡最后無(wú)響應(yīng)只能強(qiáng)殺進(jìn)程。排查泄漏比較直接的手段是連續(xù)玩十局每局結(jié)束后觀察內(nèi)存是否回落不回落的那個(gè)對(duì)象清單就是嫌疑目標(biāo)。4.3 合法域名與遠(yuǎn)程資源上線前網(wǎng)絡(luò)這關(guān)如果你的資源里有任何遠(yuǎn)程加載——不管是音頻、圖片還是排行榜接口——上線前必須在小游戲管理后臺(tái)配置 request 和 downloadFile 的合法域名且必須是 HTTPS 并有有效證書。開發(fā)階段可以靠工具里的不校驗(yàn)域名選項(xiàng)繞過(guò)但正式版本這條繞不過(guò)去。這一關(guān)容易翻車域名配了但沒(méi)帶端口號(hào)或者證書只支持了 PC 端瀏覽器到了微信里就請(qǐng)求失敗。最省事的檢查方式是先在開發(fā)者工具里關(guān)閉“不校驗(yàn)合法域名”重新預(yù)覽一遍所有網(wǎng)絡(luò)請(qǐng)求都通了再提審。5. 避坑打包微信小游戲我踩過(guò)的 5 個(gè)坑5.1 現(xiàn)象預(yù)覽正常微信開發(fā)者工具白屏第一次在微信開發(fā)者工具中導(dǎo)入構(gòu)建產(chǎn)物時(shí)最常碰見的就是一片白屏console 欄沒(méi)有任何明顯報(bào)錯(cuò)或者只有一句“game.js 加載失敗”。原因多半不是代碼問(wèn)題而是構(gòu)建產(chǎn)物目錄選錯(cuò)了。有人把整個(gè)整個(gè) Cocos 工程目錄導(dǎo)進(jìn)了微信開發(fā)者工具而微信小游戲要求導(dǎo)入的是構(gòu)建生成的 wechatgame 這個(gè)子目錄。解決方法是重新導(dǎo)入項(xiàng)目目錄字段指向 build/wechatgame同時(shí)檢查 project.config.json 存在且完整。從那次之后我每次構(gòu)建完都會(huì)先看一眼 wechatgame 里有沒(méi)有 game.js再導(dǎo)入開發(fā)者工具。5.2 現(xiàn)象觸摸事件時(shí)靈時(shí)不靈鼠標(biāo)點(diǎn)擊正常在 Cocos 編輯器預(yù)覽時(shí)點(diǎn)哪都能觸發(fā)跳躍到了微信小游戲真機(jī)預(yù)覽發(fā)現(xiàn)有時(shí)候手指點(diǎn)了沒(méi)反應(yīng)。原因在于監(jiān)聽事件類型選錯(cuò)了。Cocos 在瀏覽器預(yù)覽模式下鼠標(biāo)事件能跑但在微信小游戲環(huán)境里必須注冊(cè)觸摸事件。解決方法是把事件監(jiān)聽換成 cc.Node.EventType.TOUCH_START不要把 TOUCH_END 當(dāng)點(diǎn)擊用因?yàn)橥婕铱赡茉诎聪滤查g就移動(dòng)手指。修復(fù)之后跳躍響應(yīng)會(huì)明顯變得更干脆這個(gè)坑在幾乎所有手機(jī)小游戲上都會(huì)遇到。5.3 現(xiàn)象構(gòu)建成功但首包超過(guò) 4MB 限制發(fā)布時(shí)微信要求首包不能超過(guò) 4MB構(gòu)建產(chǎn)物明明不大一壓縮卻總超限。原因通常是“分離引擎”、“調(diào)試模式”或多余模塊還開著。調(diào)試模式下引擎不壓縮包體會(huì)明顯膨脹。解決方法是發(fā)布前打開構(gòu)建面板關(guān)掉“調(diào)試模式”再執(zhí)行一次模塊裁剪把不用的物理、粒子、視頻模塊全都去掉。裁剪后如果還超再走遠(yuǎn)程資源和分包的路。值得注意的是4MB 是“首包加載時(shí)下載量”的限制不是壓縮包總大小所以遠(yuǎn)程資源這種“首包不下載”的方案才有用。5.4 現(xiàn)象真機(jī)聲音不出來(lái)模擬器里好好的音頻只在模擬器里能響真機(jī)卻鴉雀無(wú)聲。常見原因是 Cocos Creator 的 AudioSource 組件在手機(jī)上默認(rèn)走了不符合小游戲音頻上下文的通道微信小游戲需要在用戶第一次觸摸屏幕后初始化音頻瀏覽器自動(dòng)播放政策也有類似限制。解決方式是確保音頻管理器在觸摸事件回調(diào)里調(diào)用一次播放函數(shù)并處理 audioEngine 的 resume 邏輯。也可以把音頻資源通過(guò)微信小游戲的 Audio 接口單獨(dú)加載避開引擎層的默認(rèn)行為。這個(gè)坑的隱蔽性在于 console 不會(huì)報(bào)錯(cuò)只能說(shuō)全靠耳朵。5.5 現(xiàn)象屏幕兩邊黑邊或全部拉伸變形不同手機(jī)的比例差異很大直接按設(shè)計(jì)分辨率全屏顯示時(shí)有的手機(jī)上下露白邊有的橫向拉伸得不像樣子。原因是沒(méi)有正確設(shè)置 Canvas 的適配策略。解決方式是 Cocos Creator 中 Canvas 組件選擇“適配屏幕寬度”和“適配屏幕高度”組合策略設(shè)計(jì)分辨率按 750x1334 來(lái)配同時(shí)背景圖或者地面做成可拉伸的九宮格。如果你在主場(chǎng)景里固定了某個(gè) Node 的大小換到細(xì)長(zhǎng)屏幕上就會(huì)出現(xiàn)擺放錯(cuò)位。給地面和背景做的每一張圖都要想到它在寬高比 19.5:9 和 16:9 上默認(rèn)撐滿。6. 復(fù)用與改造給組件加個(gè)調(diào)試熱區(qū)任何玩法都能裝進(jìn)這套殼嚴(yán)格來(lái)說(shuō)元導(dǎo)入這份源碼后你拿到的不只是小鳥跳躍這一個(gè)玩法而是一套通用的“單鍵反應(yīng)游戲”框架一個(gè)可控制對(duì)象、一組障礙生成、一個(gè)碰撞反饋。想把它改造成別的小游戲我習(xí)慣從兩個(gè)點(diǎn)入手。第一是為主角控制腳本加一個(gè)調(diào)試熱區(qū)讓未在編輯器中選中對(duì)象時(shí)也能在真機(jī)上手動(dòng)拉起跳躍事件。第二是抽出計(jì)分與存檔邏輯本地緩存最高分避免每局都清零。這類改造不復(fù)雜但特別省事?lián)Q游戲內(nèi)容時(shí)我們不用動(dòng)心跳邏輯只換預(yù)制體資源和參數(shù)。具體做法是在 GameManager 腳本里加一個(gè) debugTouchEnabled 屬性默認(rèn)在場(chǎng)景里打開。偽代碼如下if (this.debugTouchEnabled) { this.node.on(cc.Node.EventType.TOUCH_START, () { this.emit(game-start); this.currentScore; }); }跑通的流程是準(zhǔn)備新玩法的幾張圖片和音效替換原工程場(chǎng)景里的資源調(diào)整 jumpSpeed、spawnInterval 和 moveSpeed 三個(gè)參數(shù)讓手感匹配新的視覺(jué)表現(xiàn)在構(gòu)建面板里重新確認(rèn)平臺(tái)為微信小游戲再走一遍構(gòu)建、導(dǎo)入、預(yù)覽。這套流程我走了很多次每次做完都更確信從復(fù)用到上線中間最值得投入的是練好那套構(gòu)建檢查和性能排查。真機(jī)預(yù)覽不是驗(yàn)證結(jié)束而是要持續(xù)開著性能面板玩幾局留意內(nèi)存和掉幀。有一次我圖省事改完碰撞體尺寸后沒(méi)有點(diǎn)保存場(chǎng)景就去構(gòu)建結(jié)果微信開發(fā)者工具里一切正常一到真機(jī)就出現(xiàn)小鳥穿管子的離奇表現(xiàn)。查找半天才發(fā)現(xiàn)碰撞體改好了但場(chǎng)景沒(méi)存構(gòu)建產(chǎn)物帶的還是舊數(shù)據(jù)。從那以后我每次在場(chǎng)景編輯器里動(dòng)過(guò)任何組件參數(shù)都強(qiáng)制定死思路先在編輯器跑一次預(yù)覽、保存場(chǎng)景、再構(gòu)建、最后微信開發(fā)者工具里重新加載。這四步順序打死不變。真心的這套源碼最能讓新手受益的不是代碼多精妙而是一個(gè)聰明的前人把那些坑替你試過(guò)了。希望幫到你順著構(gòu)建流程走一遍你會(huì)對(duì) Cocos 里“打包小游戲”這件事徹底脫敏。本文還有配套的精品資源點(diǎn)擊獲取