文档中心 > 开发指南

一、支持情况

目前,Cocos、Laya 已经完成了自身引擎及其工具对淘宝小游戏的适配和支持,对应的官方文档已经对接入淘宝小游戏开发做了介绍。

引擎

版本

Cocos

3.x版本:https://docs.cocos.com/creator/manual/zh/editor/publish/publish-taobao-mini-game.html

2.x版本:https://docs.cocos.com/creator/2.4/manual/zh/publish/publish-taobao-mini-game.html

注意:Cocos最低支持版本是2.4.12,低于2.4.12版本不支持。

LayaBox

LayaAir3.x在3.1.1及后续版本支持淘宝小游戏,下载使用地址:https://layaair.layabox.com/#/engineDownload

LayaAir2.x在2.13.4及后续版本支持淘宝小游戏,下载使用地址:https://ldc2.layabox.com/layadownload/?type=layaairide-LayaAir%20IDE%202.13.4

二、小游戏是一个不同于浏览器的运行环境

一段 JavaScript 代码在运行时可以调用的 API 是依赖于 宿主环境 的。我们最常用的console.log 甚至都不是 JavaScript 语言核心的一部分,而是浏览器这个宿主环境提供的。常见的宿主环境有浏览器、Node.js 等。浏览器有 BOM 和 DOM API,而 Node.js 则没有;Node.js 有 fs、net 等 Node.js 核心模块提供的文件、网络 API,而浏览器则不具备这些模块。

小游戏的运行环境是一个不同于浏览器的宿主环境,没有提供 BOM 和 DOM API,提供的是 my API,开发者可以调用 Native 提供的绘制、音视频、网络、文件等能力。

如果你想创建画布,你需要调用 my.createCanvas()

let canvas = my.createCanvas()
let context = canvas.getContext('2d')

如果你想创建一个音频对象,你需要调用 my.createInnerAudioContext()

let audio = my.createInnerAudioContext()
// src 地址仅作演示,并不真实存在
audio.src = 'bgm.mp3'
audio.play()

但是基于 HTML5 的游戏引擎会通过以下方式去创建画布、音频,获取屏幕宽高

let canvas = document.createElement('canvas')
let audio = document.createElement('audio')
console.log(window.innerWidth)
console.log(window.innerHeight)

此时会产生错误,理由如前文所述,小游戏这个宿主环境根本没有提供 document 和 window 这两个在浏览器中内置的全局变量。因为小游戏环境是一个不同于浏览器的宿主环境。

ReferenceError: document is not defined
ReferenceError: window is not defined

所以,基本上所有基于 HTML5 的游戏引擎都不能直接迁移到小游戏中使用,因为引擎可能或多或少都用到了 BOM 和 DOM 这些浏览器环境特有的 API。只有对引擎进行改造,将对 BOM 和 DOM API 的调用改成 my API 的调用,引擎才能运行在小游戏环境中。

除了修改引擎,还有一种适配方式,即在引擎和游戏逻辑代码之间加一层模拟 BOM 和 DOM API 的适配层,我们称之为 Adaptor。这层适配层在全局通过 my API 模拟了引擎会访问到的那部分 window 和 document 对象的属性和方法,使引擎感受不到环境的差异。

三、使用其他游戏引擎

除去Cocos与Laya,开发者如果想用其他 HTML5 游戏引擎来开发小游戏也是可以的,但需要对其进行修改。修改思路建议为先实现 Adaptor 并尝试运行,再把遇到的问题逐个解决。

四、全局变量

淘宝小游戏中不支持全局变量的直接挂载和访问,这一点可能与其他平台有差异,需额外注意。

例如以下的写法会导致报错,该现象往往出现在跨脚本文件之间的相互访问。

// 文件A中定义函数testFn
var testFn = function() {
    console.log("test")
}
// 文件B中引入A
require("A.js");

// 直接调用testFn函数会报错
testFn();

淘宝小游戏提供了统一的全局变量 $global,开发者可手动挂载方法到$global上,即可解决问题。

具体示例如下,修改文件A:

// 文件A中定义函数testFn
var testFn = function() {
    console.log("test")
}
// 手动挂载到$global上,推荐一般的业务内变量挂载到 $global.window
$global.window.testFn = testFn;

文件B中通过以下方式调用函数:

// 文件B中引入A
require("A.js");
// 调用函数
$global.window.testFn(); // 正确输出 -> test

使用Cocos引擎需注意的

使用Cocos开发时可在构建面板填写全局变量,抹平与其他平台的差异。引擎在构建发布时会帮开发者自动在各文件中注入全局变量。


如填写foo,各个脚本文件中就会在头部自动定义好变量,即可无视平台差异。实现原理具体如下:

// 自动注入在各脚本文件中,无需再手动定义
var window = $global;
var foo = window.foo;

五、常见问题

1. 'global-variables.js' 说明

window 变量是 global 的引用,需要先确保 global上变量已经存在,定义的临时变量才会有值。若使用自定义脚本或使用第三方插件,发现全局变量不存在,通常是加载时机问题导致脚本还没被加载,就使用到了脚本内的全局变量。

2. spine动画顺序播放,出现部分图片显示不出来,或者渲染部分不显示。

Spine在小游戏上存在问题,请使用如下代码暂时修复问题:

et oldClear = sp.spine.IntSet.prototype.clear
sp.spine.IntSet.prototype.clear = function() {
oldClear.apply(this);
this.array = [];
}

3. 分包加载失败:Error: Failed to load subpackage

① 确保是小游戏(新)类型。

② IDE的【详情】的【项目配置】打开云构建。

③ 分包文件大小不能超过4M。

④ 主场景要放在主包里面,不能放在分包里面。

4. 淘宝开发者工具的模拟器正常播放音效,但是使用真机测试却没有声音?

临时方案处理:

\ProgramData\cocos\editors\Creator\3.8.3\resources\resources\3d\engine\pal\minigame\taobao_minigame.ts路径文件中的方法createInnerAudioContext

// eslint-disable-next-line func-names
minigame.createInnerAudioContext = function (): InnerAudioContext {
  // NOTE: `onCanPlay` is not standard minigame interface,
  // so here we mark audio as type of any
  const audio: any = polyfilledCreateInnerAudio();
  audio.onCanplay = audio.onCanPlay.bind(audio);
  delete audio.onCanPlay;
  return audio as InnerAudioContext;
};

删除两行代码:

audio.onCanplay = audio.onCanPlay.bind(audio);

delete audio.onCanPlay;

5. cocoscreator 3.x 版本小游戏在开发者工具上能正常加载音频资源,但是真机调试时加载音频资源无报错也无回调。

CocosCreator 3.8.5修复这个问题;开发者可以参考:https://github.com/cocos/cocos-engine/pull/16958

6. box2d出现xxx is not a constructor,怎么处理?

修改脚本:cocos\editors\Creator\2.4.13\resources\engine\cocos2d\core\physics\box2d-adapter.js

7. 在cocos遇到创建的对象移出屏幕外后回归到屏幕内,显示不完整,怎么处理?

如果有开启动态合图,请尝试关闭;

8. 在cocos中使用空应用@tbmp/mp-cloud-sdk初始化失败,怎么处理?

如果在Cocos工程中直接引入@tbmp/mp-cloud-sdk的话,初始化的方式有所改变:

import cloud from '@tbmp/mp-cloud-sdk';

let cloudObject = new cloud.Cloud();
try {
  cloudObject.init({
    env: 'online'
  });
}catch (e) {
  console.error("cloud初始化错误:" + e);
}

之后的操作需要使用cloundObject来进行。比如之前在淘宝小游戏项目中调用http接口的:

const result = await cloud.application.httpRequest({...});

在cocos中的调用是:

const result = await cloudObject.application.httpRequest({...});

FAQ

关于此文档暂时还没有FAQ
返回
顶部