普通小游戏开发
开放能力(必读)
社交转发裂变
数据分析
视频拍摄器
API
多端支持
自2022年9月6日起,本文档站不再更新内容,相关文档已迁移至全新“抖音开放平台”前往

字节跳动小游戏

字节跳动小游戏是一种开放能力。允许用户基于给定的 API 编写游戏代码,最终生成可运行在接入小游戏功能的各产品 APP 上。

快速上手

安装开发工具

前往开发者工具下载页面,根据自己的操作系统下载对应的安装包进行安装。

文件结构

.
├── game.js               =>  小游戏入口文件
├── game.json             =>  小游戏配置文件
└── project.config.json   =>  工程配置文件

以上三个文件为小游戏的三个必要文件,开发者如有其它资源可以在根目录下自由建立 js, audio, images 等目录,规范自己的开发文件。

配置

详细说明可见小游戏配置

game.json 示例

{
  "deviceOrientation": "portrait"
}

deviceOrientation

说明

portrait

竖屏

landscape

横屏

project.config.json 示例

{
  "description": "项目描述",
  "setting": {
    "es6": true // 声明使用的 js 语法版本
  }
}

平台能力

tt API

本平台只能使用 JavaScript 来编写小游戏。小游戏的运行环境是一个 绑定了一些方法的 JavaScript VM。不同于浏览器,这个运行环境没有 BOMDOM API,只有 tt系列 API。接下来我们将介绍如何用 tt API 来完成创建画布、绘制图形、显示图片以及响应用户交互等基础功能。

创建 Canvas

var canvas = tt.createCanvas();

通过调用 tt.createCanvas() 接口,可以创建一个 Canvas 对象。用户第一次调用时, 获取到的是一个上屏 Canvas,该 Canvas 已经显示在了屏幕上,且与屏幕等宽等高。小游戏运行期间,有且仅有一个上屏 Canvas。

绘制

var context = canvas.getContext("2d");
context.fillStyle = "#ff00ff";
context.fillRect(0, 0, 100, 100);

触摸事件

平台提供了一系列监听触摸事件的 API:

动画能力

开发者可以利用定时器相关 API 实现动画效果,如下

全局对象

小游戏的运行环境不同于 Web 环境,在真机上运行时,没有BOM API,因此也就没有 window 对象以及其上面的各种属性。所以,从 H5 迁移过来的游戏,开发者需要自己实现 window 对象的兼容(如果是利用游戏引擎开发的小游戏,导出的小游戏版本一般已经包含了一份 adapter,适配了 window 对象)。同时,在小游戏的运行环境中,提供了全局对象 GameGlobal,所有全局定义的变量都是 GameGlobal 的属性。如:

setTimeout === GameGlobal.setTimeout; // true
requestAnimationFrame === GameGlobal.requestAnimationFrame; // true

同时,GameGlobal 是一个全局对象,也是一个循环引用的对象。

GameGlobal.GameGlobal === GameGlobal;

关系链数据使用

为了丰富游戏的社交、对战玩法,目前在字节跳动平台上,对于部分宿主 APP(如抖音),我们为小游戏提供了获取关系链数据的 API:

该接口返回的数据结构可参考 API 文档。除此之外,我们还提供了配套的操作用户数据的一系列 API:

开放数据域

为了让开发者安全使用平台的关系数据,我们提供了一个名为开放数据域的环境。这是一个封闭、独立的 JavaScript 作用域。通过在 game.json 中添加配置项 openDataContext 指定开放数据域的代码目录,来开启该项功能,以便使用对应的关系链数据接口,同时,在使用这一功能时,也会有一些限制。

{
  "deviceOrientation": "portrait",
  "openDataContext": "src/myOpenDataContext"
}

对应的代码目录应该如下:

├── src
|   └── myOpenDataContext
|       ├── index.js
|       └── ...
├── game.js
├── game.json
└── ...

index.js 作为开放数据域的入口文件是必需的,平台构建工具会将开放数据目录下的文件自动打包为一个独立文件,其代码运行在开放数据域。而 game.js 其代码运行在主域。

注意:

  • 主域和开放数据域中的代码不能相互 require。

主域和开放数据域的通信

开放数据域不能向主域发送消息。

主域可以向开放数据域发送消息。调用 tt.getOpenDataContext() 方法可以获取开放数据域实例,调用实例上的 OpenDataContext.postMessage() 方法可以向开放数据域发送消息。

// game.js
const openDataContext = tt.getOpenDataContext();
openDataContext.postMessage({
  text: "This is a test.",
});

在开放数据域中通过 tt.onMessage() 方法可以监听从主域发来的消息

// src/myOpenDataContext/index.js
tt.onMessage((data) => {
  console.log(data);
  /* {
    text: 'This is a test.',
  } */
});

如何使用关系链数据

通过关系链 API 获取到的用户数据,在绘制排行榜等业务场景下如果想要展示,需要将排行榜绘制到 sharedCanvas 上,再在主域将 sharedCanvas 渲染上屏。可参考以下示例代码:

  1. sharedCanvas 是主域和开放数据域都可以访问的一个离屏画布。在开放数据域调用 tt.getSharedCanvas() 将返回 sharedCanvas。根据业务逻辑获取关系链数据,然后绘制到 sharedCanvas 上。
// src/myOpenDataContext/index.js
const sharedCanvas = tt.getSharedCanvas();
const context = sharedCanvas.getContext("2d");

function drawRankList(data) {
  data.forEach((item, index) => {
    // ...
    context.fillStyle = "red";
    context.fillRect(0, 0, 100, 100);
  });
}

tt.getCloudStorageByRelation({
  success: (res) => {
    const data = res.data;
    drawRankList(data);
  },
});
  1. 在主域中可以通过开放数据域实例访问 sharedCanvas,通过 drawImage() 方法可以将 sharedCanvas 绘制到上屏画布。
// game.js
const openDataContext = tt.getOpenDataContext();
const sharedCanvas = openDataContext.canvas;

const canvas = tt.createCanvas();
const context = canvas.getContext("2d");
context.drawImage(sharedCanvas, 0, 0);

sharedCanvas 的宽高只能在主域设置,不能在开放数据域中设置。本质上其也是一个离屏 Canvas,而重设 Canvas 的宽高会清空 Canvas 上的内容。所以可以通过 postMessage 通知开放数据域去重绘 sharedCanvas 。

// game.js
sharedCanvas.width = 400;
sharedCanvas.height = 200;

openDataContext.postMessage({
  command: "render",
});
// src/myOpenDataContext/index.js
openDataContext.onMessage((data) => {
  if (data.command === "render") {
    // ... 重绘 sharedCanvas
  }
});

运行时限制

主域

  1. sharedCanvas 只能被绘制到上屏 canvas 上。
  2. 上屏 canvas 不能调用 toDataURL,其 context 不能调用 getImageData、readPixels。
  3. sharedCanvas 不能调用 toDataURL 和 getContext。
  4. 不能将上屏 canvas 和 sharedCanvas 以任意形式绘制到其他 canvas 上,包括 drawImage、createPattern、texImage2D、texSubImage2D。
  5. sharedCanvas 的宽高只能在主域设置

开放数据域

  1. 不能设置 sharedCanvas 的宽高
  2. 开放数据域的 Image 只能使用本地或者是通过 tt.xx 系列 API 拿到的平台本身的用户头像图片,不能使用开发者自己服务器上的图片。对于非本地或非用户头像图片,可以先从主域 tt.downloadFile() 下载图片文件,再通过 OpenDataContext.postMessage() 把文件路径传给开放数据域去使用。

开放数据域只能调用有限的 API,如下所示:

  • 所有定时器相关 API
  • 所有触摸事件 API
  • tt.createCanvas()
  • tt.createImage()
  • tt.getUserCloudStorage()
  • tt.setUserCloudStorage()
  • tt.removeUserCloudStorage()
  • tt.onMessage()

开放能力

平台允许开发者可以利用一些产品宿主提供的如登录,分享,以及不久的未来支持的支付,广告等一系列开放能力,用以完善自己的产品逻辑和体验。具体可以参考开放能力一栏。

其他说明

代码包限制

IDE 1.1.0 及以上版本,小游戏包体积限制分为两种情况,普通非分包小游戏和分包小游戏。

普通小游戏包

未配置分包的场景下,每个小游戏允许上传的代码包总大小上限为 16MB

分包后小游戏包

对于配置了分包的小游戏,默认限制为:

  • 小游戏整体包(小游戏包整个目录)大小不超过 20M;
  • 单个主包不超过 4M;
  • 单个分包大小不超过 20MB。

开放数据域

开放数据域文件类似子包概念,该文件 / 目录的大小不超过 4MB。

说明

分包的应用场景在于减少小游戏加载耗时,以及提供额外的扩展包大小。普通小游戏包的压缩后大小依赖于开发者的资源,不可控。

IDE 的包大小计算不会包含:unix dot 隐藏文件及目录、node_modules 文件、js.map 文件,超过大小上限的小游戏包,预览上传将受限,请开发者注意小游戏包体积。

文件类型

小游戏限制了可以上传的文件类型。只有在以下列表中的文件可以上传成功:


类型

文件后缀类型

.png, .jpg, .jpeg, .gif, .svg, .json, .cer, .mp3, .aac, .m4a, .mp4, .wav, .flac, .ape, .ogg, .wma, .midi, .ogv, .webm, .mkv, .ttc, .ttf, .woff, .otf, .obj, .dae, .fbx, .mtl, .stl, .3ds, .pvr, .plist, .fnt, .gz, .ccz, .bmp, .atlas, .swf, .ani, .part, .proto, .bin, .sk, .mipmaps, .txt, .zip, .tt, .map, .silk, .dbbin, .dbmv, .etc, .lmat, .lm, .ls, .lh, .lani, .lav, .lsani, .ltc, .xml, .pkm, .scene, .csv, .prefab, .mesh

点击纠错
该文档是否对你的开发有所帮助?
有帮助
没帮助
该文档是否对你的开发有所帮助?
有帮助
没帮助