小遊戲從0到1:第 2 課 創建第一個小遊戲項目

目錄

<code>瞭解運行機制 註冊開發者帳號 安裝開發工具 創建第一個項目 預覽項目 自動預覽項目 熟悉項目結構 如何調試代碼 本課源碼/<code>

文 / 石橋碼農

本文約 11982 字符,閱讀需要 17 分鐘

微信小遊戲是小程序的一個特殊分支,其執行環境和運行機制和小程序是一樣的。

瞭解運行機制

微信在發佈小程序之前,有一個佐助微信 Html5 頁面開發的 WeixinJSSDK,地址是這個:

<code>//developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html /<code>

後來這個 SDK 幾經發展,就演變成了小程序 / 小遊戲底層的 WeixinJSBridge,如下所示:

WeixinJSBridge 可以看作是小程序 / 小遊戲與微信 App 之間的一個橋樑。手機操作系統的本地存儲、網絡、羅盤、陀螺儀等硬件能力,小程序 / 小遊戲都可以通過 WeixinJSBridge 訪問。

在小程序 / 小遊戲應用中,共有兩個層次:

左邊是視圖層,負責視圖的渲染。在小程序裡主要渲染 WXML、WXSS、WXS 等這些內容;在小遊戲裡沒有 WXML 組件,主要使用 Canvas 渲染視圖。右邊是邏輯層,負責 js 代碼的執行。

不同的宿主環境對這兩個層次的實現具有不同的方式:

在 iOS 手機上,視圖層渲染是基於 iOS 的 WKWebView 實現的,邏輯層運行在 JavaScriptCore 中。在 Android 手機上,視圖層渲染是微信基於 Mobile Chrome 內核自研的 XWeb 引擎渲染的,邏輯層代碼則是運行在谷歌瀏覽器 V8 引擎中。V8 是一個由 Google 開發的開源 JavaScript 引擎,這個引擎在第 1 課中我們曾經提到過。在微信開發者工具中,視圖層渲染是基於 Chromium Webview 實現的,邏輯層運行在 NW.js(//nwjs.io)中。Chromium 是 Google 谷歌瀏覽器背後的引擎,國內大多數雙核瀏覽器都採用了 Chromium 內核。NW.js 原名 Node-Webkit,是一個基於 Chromium 和 Node.js 的應用運行時,通過它可以用 HTML 和 JS 編寫原生應用程序。

這兩個層次雖然在不同的平臺上有不同的實現方式,但在所有平臺上卻具有相同的協作方式。

在邏輯層的 JS 代碼中,像 setData 這樣的方法想發揮作用,是通過 WeixinJSBridge 調用底層的 evaluateJavaScript 函數實現的;在視圖層,如果有用戶輸入,例如單擊了一個按鈕,這個按鈕上我們事先綁定過一個函數,那麼這個函數也是通過 evaluateJavaScript 間接被調用的。

evaluateJavaScript 方法有一個問題,就是執行效率太低。在執行時,它是先將數據對象轉換為字符串,再將字符串與 JS 代碼拼接成一份腳本文本後再執行。往來調用都是這樣的一種模式,重複且單調。兩個模塊是獨立的,並不存在直接的調用渠道。具體可以看下面這個示例感受下:

<code>String js = "javascript:" + functionName + "('" + s + "')"; mWebview.evaluateJavascript (js, new ValueCallback() { @Override public void onReceiveValue (String value) { ... } }); /<code>

這是一段 Java 代碼,是在 Android 應用中通過調用 webview 對象的 evaluateJavascript 方法,達到執行 js 代碼的目的。第一行中 js 即是一段準備執行的代碼文本。

兩個層次單通道通訊,不能併發,往來都要文本與對象先轉換一下,這是小遊戲 / 小程序中產生性能瓶頸的最大禍首之一,在開發中尤其值得注意。在小程序開發中,JS 是主要的編程語言,但是微信又創造了一個 WXS 語言,用於在 WXML 中編寫操作 DOM 元素的代碼,並且還不能與邏輯層的代碼進行直接的交互,其目的就是為了解決這個性能瓶頸。

但是對於初學者,在目前階段瞭解這些運行機制就足夠了,接下來我們開始創建並運行自己的第一個小遊戲項目。

創建小遊戲項目需要一個開發帳號,和一個微信開發者工具。我們先解決第一個問題。

註冊開發者帳號

如果之前註冊過小程序帳號,這個帳號能否直接用於小遊戲開發呢?

這是不可以的,雖然說小遊戲是小程序的一個特殊類目下的分支,但兩者帳號是互斥獨立的。並且一個郵箱只能註冊一個帳號,如果用它註冊過小程序帳號,註冊小遊戲帳號就不能再用了。

打開微信公眾平臺 mp.weixin.qq.com,選擇第三個分類「小程序」,開始註冊一個小遊戲帳號。註冊過程按提示即可完成。註冊完成後登陸帳號,打開設置 -> 開發設置,記錄下 AppID 備用。例如筆者的 AppID 是 wx2e4e259c69153e40,這個 AppID 在接下來創建項目時會用到。

有人問,能否用別人的 AppID 開發?

這是不可以的。微信開發者工具需要微信登陸,如果與小遊戲綁定的微信不一致,會報 “登錄用戶不是該小程序的開發者” 錯誤。

注意:在註冊小遊戲帳號時,注意在選擇服務類目時,一定要選擇遊戲類目。如果選擇了非遊戲類目,則該帳號只能用於小程序開發了。微信是以服務類目區分小程序和小遊戲的。

有了小遊戲帳號,接下來我們還需要安裝一個微信開發者工具,它是微信開發的專用於開發小遊戲 / 小程序項目的 IDE(集成開發環境),集成了項目開發需要的所有工具,包括代碼管理都有包含。

安裝開發工具

在小程序 / 小遊戲上線之前,微信開發者工具就已經存在了,當時它只用於微信內 Html5 頁面的開發調試。

在工具的選擇上,除了微信官方提供的微信開發者工具,還有像 Egret Wing 等第三方集成開發環境,也可以根據需要自由選擇。也有人使用 Webstorm、Vim、Sublime Text 3、VSCode 作為小遊戲項目的開發工具。

但對於初學者來言,建議使用官方出品的工具。官方工具不僅可以開發項目,還附有項目發佈、雲開發管理、代碼管理等內置工具,與微信提供的基礎庫版本最為契合,更新也最為及時。

如何下載呢,前往微信開發者工具下載頁面:

<code>//developers.weixin.qq.com/minigame/dev/devtools/download.html /<code>

下載、解壓並按照提示安裝即可。

微信開發者工具是跨平臺的,有三個版本:windows 64 版本、 windows 32 版本和 mac 版本。

開發者可根據自己的操作系統選擇,蘋果用戶選擇 mac 版本,大多數 windows 用戶應該選擇 windows64 版本,只有極少數 xp 用戶和 windows7 用戶選擇 windows32 版本。

工欲善其事,必先利其器。在安裝了微信開發者工具之後,為了方便開發,提升編碼效率,最好對開發環境做一些簡單配置。

打開微信開發者工具,選擇菜單設置 -> 編輯設置,將文件保存下的除「修改文件時自動保存」之外的其它選項全部選中。這樣在開發時,當修改文件時不需要頻繁地手動保存文件,文件會自動保存;當需要預覽變化時,直接單擊「編譯」按鈕就可以了。

創建第一個項目

現在我們有了帳號和開發者工具,也配置好了環境,準備工作做完了,接下來我們基於項目模板,快速創建一個小遊戲項目,並讓這個項目運行起來,開始建立對小遊戲開發的初步認識。

打開微信開發者工具,選擇小程序項目 -> 小遊戲 -> 新建項目,打開如下所示的項目創建面板:

項目名稱隨意,可以填寫 “人生第一個小遊戲項目” 或者其它名稱。目錄,選擇一個空目錄。AppID 填寫先前在本課第二步記錄下的 AppID。後端服務可以選擇「不使用雲服務」,或「小程序・雲開發」都可以。雲開發是一種後端開發技術,在後面課程中會有介紹。

當一個空目錄作為目標目標被選用時,並且 AppID 是小遊戲帳號的 AppID,此時點擊「創建」,工具將自動基於模板創建一個小飛機遊戲項目。

有人問,為什麼我創建的不是小飛機項目?

這時候要檢查一下 AppID 是否輸入 —— 因為創建項目是可以不填寫 AppID 而使用測試號的,以及輸入的是不是小遊戲的 AppID。如果不是 AppID 的問題,要檢查一下目標目錄是不是空目錄。

如果沒有註冊小遊戲帳號,也可以單擊使用「測試號」,進入體驗模式。通過體驗模式創建的項目,一些功能諸如上傳 / 預覽等不能使用,一些開放接口諸如登陸、拉取用戶信息等不能調用。

項目創建之後,如何查看運行效果呢?怎麼樣在手機上運行呢?

預覽項目

有兩種方法:在微信開發者工具的模擬器中預覽和真機上預覽。

點擊工具欄上的「編譯」按鈕,即可在左側的模擬器區域看到小遊戲的運行效果。

點擊「編譯」按鈕旁邊的「預覽」按鈕,通過微信掃一掃二維碼,即可在手機上預覽這個「打飛機」小遊戲。

這是一個不錯的小遊戲,左右滑屏即可操作我方飛機橫向移動。必須小心避過敵機,否則生命值會損耗,當沒有生命時遊戲就結束了。我方炮彈是自動發射的,當炮彈撞上敵機,屏幕上就會出現一個爆炸的效果。大家有沒有想過這個效果是怎麼實現的?

每炸掉一個敵機得一分。有對抗,有分數,這基本是一個完備的小遊戲了。唯一設計上不足的地方,是當我方飛機不動時,自動發射的炮彈將前方敵機掃清了,敵機是很難撞到我方飛機的。

現在我們放下游戲,稍後還會深入講解它的實現,我們接著看微信開發者工具的功能。預覽有兩種選擇:二維碼預覽和自動預覽。

默認是二維碼預覽,待項目編譯並且代碼包上傳完成後,二維碼自動呈現,微信掃一掃即可在手機上查看。但每次修改後都要拿起手機掃碼,這在開發中實在有些麻煩。

另一個自動預覽的功能,是微信後來添加的。單擊自動預覽分欄下的「編譯並預覽」按鈕,手機上將自動打開遊戲。

自動預覽這個功能可以避免每次掃描二維碼的麻煩。但有人發現,有時候發現單擊「編譯並預覽」,手機上沒有反應,這是怎麼回事呢?

自動預覽功能至少需要微信掃描過一次預覽二維碼。先使用一次二維碼預覽功能,再使用自動預覽就沒有問題了。如果微信換帳號重新登陸過或微信 App 重裝過,也需要重新掃碼。

自動預覽功能,是手機微信上已經測試過一次的小遊戲項目,與微信開發者工具之間建立了通訊連接而達成的。並且這種鏈接與在不在同一個局域網沒有關係,即使電腦用 Wifi,手機用 4G 也不影響。兩者之間的通訊就像兩個微信好友之間的消息收發一樣,一個發出去,另一個收到,兩者之間雖然沒有長連接,但基本可以保證「實時」同步。

有的開發者說,這個自動預覽功能雖然不用掃碼,但每次都要點一遍預覽 -> 自動預覽 -> 編譯並預覽,這個工作真是重複枯燥單調無價值。好吧,筆者也承認這一點,甚至有時候在點擊了「編譯並預覽」後,都要等上老半天。

為了解決這個問題,我們可以使用微信開發者工具提供的外部調用功能,監聽項目文件變動,以此實現真正的自動預覽。

自動預覽項目

微信開發者工具調用功能,提供兩種方式:HTTP 服務與命令行。我們先看一下 HTTP 服務怎麼使用。打開微信開發者工具,選擇菜單設置 -> 安全設置 -> 安全,開啟服務端口,並記錄下這個端口號:

例如筆者開啟的端口是 23374。然後在瀏覽器中輸入:

<code>http://127.0.0.1:23374/open?projectpath=/Users/石橋碼農/WeChatProjects/minigame-1/<code>

projectpath 代表項目地址,/Users/石橋碼農/WeChatProjects/minigame-1 是筆者創建的小遊戲項目目錄,讀者在執行時需要換成自己的地址。

當嘗試打開這個鏈接時,微信開發者工具將被喚起並自動打開 projectpath 參數指定的小遊戲項目。這就是 HTTP 服務,open 代表打開,在微信官方文檔上還有其它命令及使用說明。

這種方式有一個缺陷,使用時微信開發者工具必須是已經啟動的,還有上面的那個服務端口每次重啟開發者工具後都會變化。使用 HTTP 服務實現真正的自動預覽並不是一個好的選擇。

除了 HTTP 服務,還可以選擇命令行。命令行不需要預先啟動,也無關端口。當筆者在終端中執行這行命令時:

<code>/Applications/wechatwebdevtools.app/Contents/MacOS/cli open /Users/石橋碼農/WeChatProjects/minigame-1/<code>

微信開發者工具同樣會被喚起並主動打開同樣的小遊戲項目。這是 mac 系統上的工具地址,在 windows 系統上路徑會有所不同,這取決於軟件在系統上安裝的路徑。命令行工具地址為:

<code>macOS: /Contents/MacOS/cli Windows: /cli.bat/<code>

例如,在 windows7 上默認微信開發者工具的安裝地址為:

<code>C:/Program Files/Tencent/微信web開發者工具/<code>

那麼對應的項目開啟命令就是:

<code>C:/Program Files/Tencent/微信web開發者工具/cli open /Users/石橋碼農/WeChatProjects/minigame-1/<code>

上面我們演示的是項目開啟,如果是自動預覽,命令名稱是 auto-preview,以 mac 為例需要執行的完整命令則是:

<code>/Applications/wechatwebdevtools.app/Contents/MacOS/cli auto-preview --project /Users/石橋碼農/WeChatProjects/minigame-1/<code>

執行這條命令後,如果最近小遊戲項目在手機上運行過,手機便會自動打開項目。

我們知道,Node.js 有一個 fs 模塊,fs.watch 方法可以實現對一個目錄的監控。當監控到項目文件有變動,就自動執行上面的那條命令,是不是就能實現真正的自動預覽呢?

為了驗證這個想法,我們在項目根目錄下新建一個 watch.js 文件,內容如下:

<code>const fs = require ("fs"); let { exec } = require ("child_process"); fs.watch ( `/Users/石橋碼農/WeChatProjects/minigame-1`, () => { exec ( `/Applications/wechatwebdevtools.app/Contents/MacOS/cli auto-preview --project /Users/石橋碼農/WeChatProjects/minigame-1`, { cwd: `/Applications/wechatwebdevtools.app/Contents/MacOS/` }, (error, stdout, stderr)=>{ console.log (error,stdout,stderr); } ) } )/<code>

在上面代碼中,我們使用了 child_process 模塊,它的 exec 方法允許我們在 js 中執行一條命令。調用語法為:

<code>child_process.exec (command [, options][, callback])/<code>

exec 有三個參數:

command,字符串,需要運行的命令,參數用空格分隔options,鍵值對象,參數之一 cwd 表示子進程的工作目錄callback,回調函數,形式為 (error, stdout, stderr)=>{}

用於實現真正的自動預覽的代碼寫好了,現在我們只要在終端裡執行 node watch.js 就可以了。當項目文件有修改時,手機微信即會打開項目。如果微信開發者工具未登陸,終端將會打印出錯誤:

<code>[error] { code: 10, message: \'Error: 錯誤 需要重新登錄 (code 10)\' }/<code>

唯一美中不足的是,這個自動預覽會讓手機微信頻繁打開項目,在手機上能累計打開十幾層小飛機遊戲,這種現象在手動操作時是很難出現的。可以使用 debouce 防抖函數改善監測功能,具體可以查看筆者的源碼。

到目前為止,我們已經創建了第一個小遊戲項目,並在手機上實現了預覽,還結合微信開發者工具的外部調用功能實現了真正的自動預覽。微信開發者工具一直都在進化,作者是以 1.02 版本撰寫的本課內容,關於項目創建面板的選項設置,及編譯、預覽功能的設定等,這些以後可能會有變化,但大致功能不會改變。如果讀者朋友在閱讀時遇到了軟件界面與課程教程不完全一致的問題,可以參考官方文檔上的這個地址:

<code>//developers.weixin.qq.com/minigame/dev/guide/# 安裝並啟動開發者工具/<code>

在成功創建並運行了項目之後,接下來讓我們花點時間熟悉一下小遊戲項目的文件目錄結構,這對於接下來的學習很有幫助。

熟悉項目結構

我們看一下上一步創建的「打飛機」項目,它在微信開發者工具資源管理器中的截圖是這樣的:

其中,game.js 是遊戲主文件,game.json 是遊戲配置文件,project.config.json 是項目配置文件。audio 目錄存放的是音頻文件,images 目錄存放的是本地圖片。js 目錄文件較多,包括以下子目錄及文件:

<code>js 目錄 ├── base // 定義遊戲開發基礎類 │ ├── animatoin.js // 幀動畫的簡易實現 │ ├── pool.js // 對象池的簡易實現 │ └── sprite.js // 遊戲基本元素精靈類 ├── libs │ ├── symbol.js // ES6 Symbol 簡易兼容 │ └── weapp-adapter.js // 小遊戲適配器 ├── npc │ └── enemy.js // 敵機類 ├── player │ ├── bullet.js // 子彈類 │ └── index.js // 玩家類 ├── runtime │ ├── background.js // 背景類 │ ├── gameinfo.js // 用於展示分數和結算界面 │ └── music.js // 全局音效管理器 ├── databus.js // 管控遊戲狀態 └── main.js // 遊戲入口主函數/<code>

這上面的所有文件,只有 game.js 與 game.json 對於小遊戲是必須的。js 目錄下的 base、libs、npc 等子目錄,並不是每個小遊戲項目都必須有的。

關於小遊戲所有的配置,都是在 game.json 文件中完成的,下面我們重點看一下這個文件。

在 game.json 裡最常用配置字段是 deviceOrientation 與 showStatusBar:

<code>{ "deviceOrientation": "portrait", "showStatusBar": false }/<code>

deviceOrientation 屬性用於設定屏幕方向,有 portrait 豎屏、landscape 橫屏兩個選項,默認為 portrait。showStatusBar 設置是否顯示系統狀態欄,默認為 false,即全屏。系統狀態欄是手機頂部有 Wifi、電量標誌的那一行區域。

現在我們對項目結構也有了初步的理解了,接下來我們瞭解小遊戲如何發佈吧,畢竟我們在本地開發遊戲,就是為了最終上傳發布。

微信開發者工具欄上有一個「上傳」按鈕:

單擊這個按鈕即將本地所有源碼壓縮成代碼包,並上傳至微信服務器。當用戶在微信裡訪問小遊戲時,是微信服務器在向用戶提供服務。

這裡有一點需要注意,代碼包有大小限制。目前每個小遊戲允許上傳的單包大小是 4mb。如果使用分包加載技術,所有分包加起來最大不允許超過 8mb。4mb 很小,有時候一張高清圖片就會超過這個限額。

但這個大小已經比小程序的限額大了一倍了。目前微信小程序單包大小限制為 2mb。這些限制隨著手機性能的提升、技術的進步和企業之間競爭的加劇,以後可能會逐步提高。

雖然代碼包有大小限制,但是在項目裡大多數資源文件,如圖片、音頻、視頻等資源,是以網絡鏈接的存在遊戲中使用的,並不佔用配額。主要的內容是代碼文本,壓縮之後最大能減少 70% 的體積,所以軟件包大小並不值得擔心。

在軟件包上傳後,開發者可以在微信公眾平臺看到待提交審核的版本。在線提交審核,待審核通過後,小遊戲就可以正式發佈了。

項目到提審、發佈這一步已經很簡單了。最重要的步驟還是開發與調試,尤其在開發中遇到 bug 時,需要儘快找到並解決問題。關於這一塊,微信開發者工具也提供了方便、全面的調試功能。

如何調試代碼

js 是小遊戲最主要的開發語言,小遊戲調試主要是調試 js 代碼。js 作為一種寄宿語言,調試方法依賴寄宿環境。在傳統的網頁開發中,可以這樣調試代碼:

使用 window.alert () 彈框展示使用 document.write () 方法將內容寫到 HTML 頁面中使用 innerHTML 寫入 HTML 元素,在頁面上呈現使用 console.log () 寫到瀏覽器控制檯,這是最常見的一種方式

在小遊戲開發中,主要使用 console 面板調試 js 代碼。使用 console.log、console.error 等方法在 console 面板打印內容。

鑑於小遊戲宿主環境的差異,有些 bug 在微信開發者工具中不存在,在手機上卻存在,這時候如何在手機上調試呢?

在手機上調試,當小遊戲運行後,點擊屏幕右上角膠囊按鈕組中的「…」按鈕,選擇「打開調試」。此時小遊戲會退出重啟,待重新打開後,屏幕右下角會有一個 vConsole 按鈕。點擊這個 vConsole 按鈕,便可以看到親切的 Console 面板及代碼中使用 console.log 打印的內容了。

有時候有些 bug 是在用戶的手機上發現的,在開發工具中和在自己的手機上都復現不了,這時候排查問題,可以使用工具欄中的「真機調試」功能。單擊該按鈕,會生成一個二維碼,將這個二維碼發給用戶。當用戶掃碼打開遊戲後,開發者的微信開發者工具會自動打開一個新的調試窗口,用戶手機上的 vConsole 輸出會自動同步到這個窗口來。

通過遠程真機調試,用戶在他的手機上進行一些操作,運行的是開發者本地的代碼,相應的打印信息開發者在本地都能看到。這是一個很方便的排查用戶 bug 的調試方法。

在使用該功能時,有一點需要注意,就是用戶必須是小遊戲帳號的測試用戶,不然用戶是無法運行開發者的測試代碼的。登陸微信公眾平臺(//mp.weixin.qq.com),使用管理員身份可以將用戶微信添加為體驗者,添加之後就可以進行遠程調試了。

本節課我們學習瞭如何創建並運行第一個小遊戲項目,還學習瞭如何在微信開發者工具中及手機上查證問題、調試代碼,調試是每個程序員都必備的技能之一,在接下來的學習中將發揮重要的作用。下一課我們將深入探究「打飛機」項目的源碼,看一看飛機是如何飛行的,又是如何控制移動的,爆炸效果是如何實現的等等。

本課源碼

<code>//git.weixin.qq.com/rxyk/wegame0to1-1/repository/archive.zip?ref=lesson2/<code>

源碼下載後解壓,打開微信開發者工具,選擇小程序項目 -> 小遊戲,單擊「+」號,選擇「導入項目」,如下所示:

將 AppID 修改為自己的小遊戲帳號 AppID,完全後即可查看調試源碼。以後各章方法同。

這篇屬於「小遊戲從 0 到 1」50 課的一部分,有什麼問題歡迎留言,也歡迎群內討論。

2019 年 5 月 7 日