必看!鸿蒙原生游戏开发保姆级指南
开篇
毋庸置疑、鸿蒙游戏生态肯定是开发者们的必争之地。
相信很多开发者都想将自己的游戏快速移植到鸿蒙操作系统上,但无奈没有时间去研究细节。
今天这篇游戏鸿蒙原生化保姆级指南,就是为大家精心准备的,希望大家能够喜欢。
开发准备
1.游戏引擎


Cocos 引擎下载:
-
https://www.cocos.com/creator
“
下载 Cocos Dashboard,推荐使用 Cocos Creator 3.8.6+ 版本。
市面上支持发布鸿蒙原生游戏的引擎数量并不多,阿麟今天就以 Cocos 引擎为例,给大家讲解如何将自己的游戏项目发布为鸿蒙原生游戏。
之所以选择 Cocos 作为讲解,主要有几个考虑。
-
目前市面上大量的小游戏都采用 Cocos 制作,这些小游戏也在寻找新的增量,鸿蒙原生游戏就是一个很好的机会。
-
Cocos 对游戏开发者开源、免费,也不收取任何后期费用,开发者没有成本负担
2.DevEco Studio


下载地址:
-
https://developer.huawei.com/consumer/cn/download/
“
下载最新稳定版即可。
DevEco Studio 是一个面向全场景多设备的一站式分布式应用开发平台,支持 HarmonyOS 和 OpenHarmony 游戏、应用及服务开发。
对于鸿蒙游戏和应用开发者来说,这个工具是必须掌握的。
3. 开发资料
作为全球第一款支持鸿蒙操作系统的游戏引擎,也作为全球率先与鸿蒙游戏生态深度合作的游戏引擎,Cocos 社区和鸿蒙游戏社区都积累了非常多的产品案例和开发资源,大家可以通过以下途径获得。
-
发布到鸿蒙:https://docs.cocos.com/creator/3.8/manual/zh/editor/publish/publish-openharmony.html
-
构建说明:https://developer.huawei.com/consumer/cn/blog/topic/03176120152473057
-
原生接口交互:https://developer.huawei.com/consumer/cn/blog/topic/03176120896060024
上面的资料已经讲明白了各个环节,接下来,阿麟就带大家走一遍流程,并指出需要重点关注的事项和风险点。


构建发布
1. 平台选择


构建发布时,平台选择记得选择 HarmonyOS NEXT,这才是我们提到的鸿蒙原生项目。
2. 脚本引擎选择


如下图所示,不同的脚本选择,会让引擎的 TS/JS 代码的运行环境不同。
-
不管如何选择, 项目中的 ArkTS 代码均在方舟引擎环境中执行。
-
选择 Ark 后,引擎中的 TS/JS 代码在方舟引擎环境中执行。
-
选择 V8 后,引擎中的 TS/JS 代码在 V8 虚拟机中执行。
-
选择 JSVM 后,引擎中的 TS/JS 代码在 JSVM 中执行。


除此之外,不同的引擎脚本环境,也影响脚本的 JIT 和 热更新功能。
引擎
JIT
热更新
JSVM
支持
支持
V8
不支持
支持
Ark
暂不支持
暂不支持
由此可见,构建鸿蒙原生游戏时,脚本引擎推荐选择 JSVM(在 v3.8.7 中会作为默认选项),在鸿蒙原生设备上,JSVM 的功耗、内存开销、性能和稳定性会优于 V8,并且会持续增强。
如果没有特殊需求,则不需要过多修改了,点击 Build(构建) 按钮,等待完成即可。
编译运行
1. 打开项目
构建完成后,启动 DevEco Studio,选择打开项目,选择 项目目录/native/engine/harmonyos-next。


“
由于平台机制问题,鸿蒙原生项目暂时只能放在 native 下。
2. 真机调试
设备要求
你要准备一台支持 HarmonyOS 5.0.1(13)以上的华为手机。
打开手机的 USB 调试
-
找到 设置->关于本机->软件版本
-
点击 软件版本 6 次,会询问你是否需要打开开发者选项,点击 确认 即可打开。
-
打开 设置->系统->开发者选项->USB 调试
-
用数据线连接打开了 DevEco Studio 项目的电脑
你应该能在 DevEco Studio 右上角发现你的设备。


设置签名
-
在 DevEco Studio 中打开 File -> Project 窗口,切换到 Singing Configs 标签。


-
勾选自动签名(Automatically generate signature)
-
如果未登录,请先登录
-
点击确认即可
3. 启动项目


点击右上角的 Run \'entry\' 或者 Debug \'entry\' 即可在真机上预览项目。
“
如果启动时提示安装失败,有可能是签名设置的问题,请再次检查签名情况。
平台标志
在项目开发中,我们一套项目代码会同时发布到多个平台。
所以通常需要根据具体平台来处理一些特定的功能。
比如鸿蒙原生系统特有的元服务卡片、碰一碰、设备流转等能力,是其他平台没有的。
相关代码就需要使用平台标志进行过滤,才能保证没有问题。
鸿蒙原生平台在 Cocos 引擎中的标志为 sys.OS.OPENHARMONY,使用下面代码即可进行判定。
improt { sys } from \'cc\';if(sys.os == sys.OS.OPENHARMONY){ // 特有的游戏逻辑}
原生通信基础
1. 目录结构
原生通信必然涉及到对项目代码进行改动,我们先来熟悉一下项目目录结构,如下图所示:
2. 运行线程
Cocos 发布出来的鸿蒙原生游戏项目,有两个线程,用于处理不同的事务。
-
主线程:用于执行 ArkTS 代码,系统原生 UI 渲染
-
Cocos 线程:用于执行引擎渲染和代码脚本
两个线程中的数据不能直接相互访问,需要通过 Worker 的通信机制才能实现。
“
在 DevEco Studio 打开的项目代码中,cocos_worker.ts 里的代码就是运行在 Cocos 线程中的,其余代码默认是在主线程。
引擎脚本调用原生
callStaticMethod
引擎提供了一个非常方便的接口来调用原生功能,函数原型如下:native.reflection.callStaticMethod(clsPath,methodName,paramStr,isSync)
-
clsPath:string:对应的函数文件位置,无需后缀名
-
methodName:string:方法名称, 模块/方法,如果模块为 entry,可以直接写方法名
-
paramStr:string:参数,如果需要传多个,则需要转为 JSON 字符串,如果无参数,则填空字符串 \'\'
-
isSync:boolean:是否为同步调用,默认为 true
新增原生代码
我们在 DevEco Studio 中新增一个代码文件,比如:src/main/ets/Test.ets
在Test.ets里,我们写一个简单的测试函数。
function test(param:string){ console.log(\'callStaticMethod_test\',param); return \'native_\' + param;}
在 entry/build_profile.json5 文件中的 buildOption 字段中,加入如下内容,以确保函数能够被正确访问(一定不要忘了!)。

我们在 Cocos 引擎中新建一个按钮,新增一个按钮响应脚本函数,写下下面的代码。
if(sys.os == sys.OS.OPENHARMONY){ let result = native.reflection.callStaticMethod(\'entry/src/main/ets/native_api/OSAbility\',\'entry/test\',\'test native call\', true); console.log(result);}
在引擎的构建面板中再次打包,并在 DevEco Studio 中新运行项目,就可以进行测试了。
“
参数和返回值仅支持 string|number|boolean 基础类型,如果需要返回对象,请使用 JSON 字符串,并做对应的序列化和反序列化。
执行线程
这里需要注意,虽然我们的 test 函数是被 Cocos 线程中的脚本调用的,但是 test 的执行环境是主线程,如下图所示:


大部分情况下,我们使用 native.reflection.callStaticMethod 是为了调用原生平台的能力(如访问电池余量、网络状态、图片读取等等),这个特性使我们在调用原生功能的时候非常方便。
同步与异步调用
为了更方便地与原生层交互,鸿蒙原生提供了同步和异步两种调用方式,我们以获取电池信息为例。
同步获取电池信息
//原生:entry/src/main/ets/native_api/OSAbility.etsfunction getBatteryInfo():string{ return JSON.stringify({ batterySOC:batteryInfo.batterySOC //电池电量百分比 ,chargingStatus:batteryInfo.chargingStatus // 电池充电状态 });}//引擎脚本:Test.tslet result = native.reflection.callStaticMethod(\'entry/src/main/ets/native_api/OSAbility\',\'entry/getBatteryInfo\',\'\', true);let batteryInfo = JSON.parse(result);
异步获取电池信息
//原生:entry/src/main/ets/native_api/OSAbility.etsfunction getBatteryInfoSync(param:string,cb:Function):void{ setTimeout(()=>{ cb(JSON.stringify({ batterySOC:batteryInfo.batterySOC //电池电量百分比 ,chargingStatus:batteryInfo.chargingStatus // 电池充电状态 })); },10);}//引擎脚本:Test.tslet result = native.reflection.callStaticMethod(\'entry/src/main/ets/native_api/OSAbility\',\'entry/getBatteryInfoSync\',\'\', false);let batteryInfo = JSON.parse(result);
“
注意1:异步调用会使引擎脚本阻塞等待,因此需要注意那种特别耗时,或者永远不会触发回调的情况。
“
注意2:v3.8.6 中实现异步调用时,即使用不上也必须保留 param:string 参数,否则调用会导致进程崩溃。(后续版本会优化)
原生调用引擎脚本
cocos.evalString
//引擎中 ABC.tswindow[\'test\'] = (str:string,n:number)=>{ console.log(str,n);}//原生层代码import cocos from \'libcocos.so\';cocos.evalString(`test(\'abc\',3)`);
如上图所示,libcocos.so 提供了一个 evalString函数,用于原生层调用 Cocos 引擎脚本中的全局函数。
线程安全
“
需要注意的是,
cocos.evalString只能在 Cocos 线程中被调用。
我们需要修改一下项目源码,才能方便调用。
1. cocos_worker.ts
在 cocos_worker.ts 中,switch case 语句里,添加如下代码,用于接收来自其他线程的 evalString 消息。
case \"evalString\": cocos.evalString(msg.param); break;
2. 调用
在需要调用 cocos.evalString 的地方,按照下面方式,向 cocos worker 线程发送消息即可。
import { WorkerManager } from \'../cocos/WorkerManager\';const cocosWorker = WorkerManager.getInstance().getWorker();cocosWorker.postMessage({ type: \"async\", data: { name:\"evalString\", param: `test(\'abc\',3)` } });
“
注意1:跨线程通信走的是 worker 间的消息机制,其性能远低于直接的函数调用,因此需要避免高频调用。
3. 覆盖处理
已知问题:v3.8.6 中,cocos_worker.ts 会在每一次构建时被还原,此问题会在 v3.8.7 中修复。
但对于 v3.8.6 的开发者,可以用下面的方式解决。
-
复制一个
cocos_worker.ts到项目根目录下(与assets平级),后期对 cocos_worker.ts 的修改,以这个文件为主 -
新建一个构建扩展
-
在构建扩展的
hook.ts中的onAfterBuild里,添加如下代码:
if(options.platform === \'harmonyos-next\' ){ let src = `${Editor.Project.path}/cocos_worker.ts`; let dest = `${Editor.Project.path}/native/engine/harmonyos-next/entry/src/main/ets/workers/cocos_worker.ts`; console.log(`copy ${src} to ${dest}`); const fs = require(\'fs\'); fs.writeFileSync(dest, fs.readFileSync(src)); }
编译扩展:
npm installnpm run build
刷新扩展后,再次打包,就可以实现 cocos_worker.ts 的修改生效了。
结束语
以上就是 Cocos 项目进行鸿蒙原生化的主要流程、经验与注意事项,通过这份指南,相信大家能够快速上手鸿蒙原生游戏开发,抢占市场先机。
后续我们还会持续分享更多鸿蒙原生适配、能力接入、开发调试等相关内容,并同步优化开发者文档,助力开发者轻松上架鸿蒙原生游戏。
欢迎关注 Cocos 官方公众号,第一时间获取更多实用信息与技术干货。



