Box3是一个基于网页的多人联机3D创作平台,支持JavaScript编程。每个地图的脚本,会在服务端运行,响应世界中的各种事件,并更新游戏引擎状态。地图脚本和游戏引擎分开运行,以确保安全,避免用户创作代码出错而引起整个游戏引擎崩溃。
代码功能非常强大,几乎能控制游戏的任何方面。举个例子,

  1. // 当玩家进入游戏
  2. world.onPlayerJoin(({ entity }) => {
  3. // 如果玩家接触到了世界中的方块
  4. entity.onVoxelContact(({ x, y, z }) => {
  5. // 将方块变成空气
  6. voxels.setVoxel(x, y, z, 0);
  7. });
  8. });
  9. console.log('Welcome to Box 3!');

这段代码会破坏掉玩家接触的任意方块。

Execution model 执行模型

由于在网页上,脚本使用基于事件的API执行。服务端的引擎状态,以64毫秒为1tick的时间间隔更新。在每一tick间,引擎会执行以下步骤:

  1. 应用来自客户端的更新
  2. 应用来自脚本的更新
  3. 更新引擎的物理状态
  4. 将状态同步到所有脚本,并安排脚本的下一tick
  5. 将更新的状态发送给所有客户端

如果脚本运行缓慢或崩溃,引擎会跳过多个tick,直到脚本不再卡住。这样能防止脚本陷入无法跟上引擎进程的循环。脚本的所有事件或更新都会同步在每tick的临界点发生。

Events 事件

每当引擎发生更改时,事件就会分派到脚本过程中。管理员可以使用 EventChannels 订阅这些事件。要订阅事件频道,请使用传入的处理程序作为参数来调用它。调用处理程序将返回一个令牌,该令牌可用于取消任何未决事件。例如:

  1. // 当玩家进入游戏
  2. world.onPlayerJoin(({ entity }) => {
  3. // 游戏运行的每一帧,向控制台输出提示
  4. const token = world.onTick(() => {
  5. console.log("tick !");
  6. });
  7. // 2秒后,结束事件
  8. setTimeout(() => {
  9. console.log('cancel tick handler');
  10. token.cancel(); // 不再记录tick事件
  11. }, 2000);
  12. });

此脚本将会在玩家进入游戏后,持续向控制台输出信息,并在2秒后结束。

World 世界

world对象是整个Box3 API的入口点。它具有枚举实体和参与者以及使用各种方法搜索世界的方法。

Voxels 方块

voxels对象可让您修改世界地形。Box3的世界地形由一个个方块构建而成,目前,地图最大支持128x128x128的地形。您可以使用voxels.setVoxel()在指定的世界坐标位置放置一个指定的方块。如:

  1. voxels.setVoxel(64, 9 ,64, 'H')
  2. voxels.setVoxel(65, 9 ,64, 'E')
  3. voxels.setVoxel(66, 9 ,64, 'L')
  4. voxels.setVoxel(67, 9 ,64, 'L')
  5. voxels.setVoxel(68, 9 ,64, 'O')

此脚本将会在对应的位置依次生成带有”HELLO”字母的方块。

Entities 实体

Box3世界中的游戏对象,被称为实体,实体具有一些物理属性,如位置,速度,还有其他的属性,如模型外观,粒子特效等。可以在脚本中调用 world.createEntity() 来创建实体,或使用相同方法复制实体。还可以通过调用实体对象身上的 entity.destroy() 来销毁该实体。在创建实体之前,需要现在游戏中添加相应的模型。

Players 玩家

Player 是 Box3 世界中具有特殊类型的实体,玩家具有特殊的属性。可以使用 world.onPlayerJoin() 捕获玩家登录的事件,或使用 world.onPlayerLeave() 方法检测玩家何时离开。