GoBigger 引擎设计

总览

本节主要说明了 GoBigger 的引擎设计,其中包括各种球的详细运动逻辑设定。如果读者想要根据 GoBigger 去开发新的环境,或者想要更深入了解 GoBigger 的研发细节,可以仔细阅读本节。为了方便阐述,我们将按顺序介绍每一种球的逻辑设定,并在其中穿插和其他球的交互过程。如果你对 GoBigger 中基础的球单位还不熟悉,建议先查阅上一节(GoBigger是什么)。注意,以下的说明均基于 st_t4p3 的设置。

所有球的共同点

  1. 在 GoBigger 中,你可以看到不同的球有不同的大小。我们定义每个球都有一定的分数 score,并通过分数可以计算出对应的半径 radius

import math

def score_to_radius(score):
    return math.sqrt(score / 100 * 0.042 + 0.15)
  1. 食物球是不可移动的,但是荆棘球,孢子球,分身球都包含速度属性,也就是说他们都可以移动。

  2. 如果两个球存在可以吃与被吃的关系(例如分身球之间,分身球和所有球,荆棘球和孢子球之间),那么当两个球出现圆心重合的情况时,将会通过判断二者分数来判断是否能发生吞噬。我们规定当大球的分数超过小球的 1.3 倍时才能发生吞噬。

  3. 所有球在运动过程中圆心都不会超出地图边界。

  4. 我们默认游戏内的 FPS20。也就是说,一秒内游戏状态会更新 20 次。同时,默认情况下每次调用 env.step 会使得环境前进两帧,用户提供的动作会在第一帧做完,然后第二帧赋予空动作。

食物球

  1. 食物球是游戏中的中立资源。在 st_t4p3 的配置中,开局时地图上的食物球数量会有 800 个,且数量上限为 900 个。每隔 8 帧,将会补充 (数量上限-当前数量)* 0.01 个食物球,并使得食物球的数量不会超过数量上限。

  2. 食物球的初始分数是 100。也就是说,如果一个分身球吃掉了一个食物球,那么这个分身球的分数会增加 100

荆棘球

  1. 也称为刺球。荆棘球也是游戏中的中立资源。在 st_t4p3 的配置中,开局时地图上的荆棘球数量会有 9 个,且数量上限为 12 个。每隔 120 帧,将会补充向上取整 (数量上限-当前数量)* 0.2 个荆棘球,并使得荆棘球的数量不会超过数量上限。

  2. 荆棘球的初始分数会从 1000015000 范围内随机选择。

  3. 当玩家向荆棘球吐孢子球的时候,如果孢子球和荆棘球发生了圆心覆盖,荆棘球会吃掉孢子球,同时往孢子球的运动方向产生一个为 10 的初速度,并且该速度在 20 帧内均匀衰减到 0

孢子球

  1. 孢子球的大小是固定的,分数固定为 1400

  2. 孢子球被吐出的时候速度是固定的,为 30,并且该速度在 20 帧内均匀衰减到 0

分身球

分身球的大小随着不断吃球而变大。分身球的初始分数为 1000。单个玩家最多拥有 16 个分身球。每个分身球的分数超过 3200 时才可以使用吐孢子 eject 技能,超过 3600 时才可以使用分裂 split 技能。

速度

分身球的速度由三部分矢量共同作用:玩家操作,多个球存在时导致的向心力,以及分裂或吃荆棘球之后带来的逐渐衰减的速度。玩家操作和向心力带来的加速度在每一帧会乘以每帧时间长度来作为速度的改变量。

  1. 玩家操作:如动作空间定义的那样,玩家可以提供一个单位圆内的任意一点 (x,y) 来改变分身球的速度。具体来说,GoBigger 会首先将这一点归一化到单位圆内(如果在圆外则归一化到圆上,否则不做处理),然后乘以权重 30 来作为加速度。

  2. 向心力:当玩家拥有多个分身球的时候,多个球内部会产生一个向心力,该力指向质心。实际上向心力不会直接使用,会除以半径之后作为真正的向心力,并乘以权重 10 来作为加速度。

  3. 分裂或吃荆棘球之后带来的逐渐衰减的速度:分身球吃掉荆棘球分裂出来的新的分身球会拥有一个分裂后新的初始速度。这个速度的模长为和分裂后的半径有关,具体为 (260 - 20 * radius) / 7,方向背离圆心。该速度会在 14 帧内均匀衰减到 0。如果分身球是通过分裂技能得到,那这个初始速度的模长的计算公式为 (95 + 19 * radius) / 7

  4. 玩家操作和向心力带来的速度会受到速度上限的限制。速度上限和球的半径有关,并会将玩家操作和向心力中较大之一来作为 ratio 对速度上限进行调整。具体公式为 (2.35 + 5.66 / radius) * ratio

吃荆棘球

  1. 分身球每次吃掉荆棘球的时候,会分裂出不超过上限 10 个新的分身球。举个例子,如果玩家当前只有两个分身球,而其中一个分身球吃掉了一个荆棘球,那他会分裂出新的 10 个分身球,因此此时该玩家总共有 12 个分身球;如果玩家当前有 10 个分身球,而其中一个分身球吃掉了一个荆棘球,那他会分裂出新的 6 个分身球,因此此时该玩家总共有 16 个分身球。

  2. 分身球吃掉荆棘球分裂出来的新球的最大分数为 5000。举个例子,分身球当前分数是 23000,他吃掉了一个分数为 10000 的荆棘球,那么他的分数就会变成 33000。与此同时,这个分身球会分裂出新的 10 个分身球,按照均匀分配,每个分身球的分数为 3000

  3. 吃荆棘球分裂之后,新增的球的位置均匀分布在周围,且总会有新增的球分身处于原始球右侧水平位置。

分裂

  1. 分裂出来新的分身球会在玩家指定的方向上,如果没有指定方向,则会出现在原始球的运动方向上。

  2. 分裂技能会将原始球的分数均分到两个分裂后的球上。

  3. 分裂出来新的分身球也会拥有原始分身球的速度。

  4. 无论是分裂后还是吃荆棘球后,玩家的分身球(包括触发分裂和吃荆棘球,以及这俩操作后新增的分身球)都会进入长度为 20 秒的冷却阶段。在冷却阶段内的分身球无法触发和自己其他的分身球合并的操作。此外,在分身球完成一次合并之后,会重新进入冷却阶段。

吐孢子

  1. 分身球执行吐孢子操作后产生的孢子球会出现在玩家指定的方向上,如果没有指定方向,则会出现在分身球的运动方向上。

  2. 分身球每吐一个孢子球,相当于把自身分数中割离了 1400 分到新的孢子球上。