# 数组

什么情况下你应该考虑使用数组?当你有一系列“相似”的数据,例如你做跑酷地图时有几十个检查点坐标需要存放时,你就可以考虑使用“数组”能不能简化你的逻辑了。

# 基础

先介绍几个基本名词:

  • 数组:一系列数据的集合。注意,与数学中的集合不同的是,数组内的元素是可以重复的。
  • 元素:也称为“值”。集合中的单个数据。
  • 索引:在编程中一般将它叫做下标或索引。它表示是集合中的第几个,从0开始计数。

例如我们有一个数组是[10, 20, 30],那么20是这个数组的第2个元素,它的索引是1。

数组的基本操作和普通变量一样,分为读取和写入。读取非常简单,使用“数组中的值”即可。写入又分为直接写入索引,或者添加到数组末尾。它们分别使用:

  • 在索引处设置全局变量(A, 索引, 值)
  • 在索引处设置玩家变量(玩家, A, 索引, 值)
  • 修改全局变量(A, 添加至数组, 值)

# 结合“索引”读写

假如我们要做一个有很多个检查点的跑酷地图,每次通过一个检查点,我们就需要给玩家创建下一个检查点的光环。如果不使用数组,我们需要写非常多的规则。但是如果使用数组,事情就会变得简单起来:

# 初始化

我们使用变量A来存放所有的检查点:

  • 设置全局变量(A, 空数组)
  • 修改全局变量(A, 添加至数组, 矢量(0, 0, 0))
  • 修改全局变量(A, 添加至数组, 矢量(10, 10, 10))
  • 修改全局变量(A, 添加至数组, 矢量(20, 20, 20))
  • 修改全局变量(A, 添加至数组, 矢量(30, 30, 30))

玩家一开始的索引是0,我们使用变量B来存放:

  • 设置玩家变量(事件玩家, B, 0)
  • 创建效果(事件玩家, 有益光环, 绿色, 数组中的值(全局变量, A, 玩家变量(事件玩家, B)), 10.000, 可见, 位置和半径)

另外,关于“创建效果”为什么在这里创建也能达到效果,在技巧与提示中有简单说明。

# 通过检查点

假设检查点的碰撞半径是10。

  • 事件:持续 - 每名玩家
  • 条件:范围内玩家(数组中的值(全局变量(A, 玩家变量(事件玩家,B)), 10.000, 所有队伍, 关闭) == 事件玩家
  • 动作:修改玩家变量(事件玩家, B, 加, 1)

# 增加可用变量

注意:合理利用数组可以让我们可以存储更多数据。但并不推荐使用数组存储一系列互相无关的数据——从设计的角度来说,这不是好事。直接读取变量肯定比读取数组更快,因此,如果能使用普通变量解决的,那么就不推荐使用数组来解决。

我们可以将一系列不相关的内容放入一个数组中,达到“增加可用变量”的目的。例如:

  • 设置玩家变量(事件玩家, A, 空数组)
  • 在索引处设置玩家变量(事件玩家, A, 0, 矢量(0, 0, 0))
  • 在索引处设置玩家变量(事件玩家, A, 1, 英雄(莱因哈特))
  • 在索引处设置玩家变量(事件玩家, A, 2, 假)

然后在别的规则中这样使用:

  • 传送(事件玩家, 数组中的值(玩家变量(事件玩家, A), 0))
  • 开始强制玩家选择英雄(事件玩家, 数组中的值(玩家变量(事件玩家, A), 1))
  • 在索引处设置玩家变量(事件玩家, A, 2, 真)

# 其他

  • 数组使用前请先初始化!(即:设置全局变量(A, 空数组))否则可能出现意料之外的结果。
  • 在某一时刻大量写入数组可能导致“服务器意外关闭”。
  • 数组的数量可以使用“数量”来获得。
  • “已排序的数组”默认使用升序排列(即从小到大)。如果你需要使用降序排序,目前请自行进行运算转换。
  • 如果你尝试读取一个不存在的索引,目前版本的结果是0。例如数组是[1, 2, 3],当你尝试使用数组中的值(数组, 3)时,结果是0,因为数组一共有三个元素,其中3的索引是2。并不存在索引为3的元素。

# 二维数组

二维数组在编程中可以说是相当基础的操作,但是大部分人都会误以为工坊只支持一维数组。

我们可以通过索引处设置变量为空数组来初始化二维数组,并在索引处修改变量来追加成员。个中细节需要配合代码来理解,例如:

  • 在索引处设置全局变量(A, 0, 空数组);
  • 在索引处修改全局变量(A, 0, 添加至数组, 1);
  • 在索引处修改全局变量(A, 0, 添加至数组, 2);
  • 在索引处修改全局变量(A, 0, 添加至数组, 矢量(111, 222, 333));

之后便可以这样读取:

  • 数组中的值(数组中的值(全局变量(A), 0), 2);

另外,二维数组中,有以下“坑”需要注意:

  • 将二维数组用作数组值的索引的第一个参数时,例如数组值的索引(某二维数组, ……),前者将会被展开为一位数组。如本来的二维数组是[[1, 2], [2, 3]],实际查找使用的是[1, 2, 2, 3]
  • 将数组用作数组值的索引的第二个参数时,例如数组值的索引(某二维数组, 某数组),会取后者的第一个值在前者中进行查找。例如数组值的索引(某二维数组, [1, 2]),实际运行的代码相当于:数组值的索引(某二维数组, 1)

例如下面动作:

  • 设置全局变量(A, 空数组);
  • 在索引处设置全局变量(A, 0, 空数组);
  • 在索引处修改全局变量(A, 0, 添加至数组, 1);
  • 在索引处修改全局变量(A, 0, 添加至数组, 2);
  • 在索引处设置全局变量(A, 1, 空数组);
  • 在索引处修改全局变量(A, 1, 添加至数组, 2);
  • 在索引处修改全局变量(A, 1, 添加至数组, 3);
  • 设置全局变量(B, 空数组);
  • 修改全局变量(B, 添加至数组, 2);
  • 修改全局变量(B, 添加至数组, 3);
  • 设置全局变量(C, 数组值的索引(全局变量(A), 全局变量(B)));

C的结果是1,因为:

  • 全局变量(A)本来为[[1, 2], [2, 3]],查找时被展开为[1, 2, 2, 3]
  • 全局变量(B)[2, 3],实际使用2进行查找。
  • 实际运行的动作相当于数组值的索引([1, 2, 2, 3], 2),因此结果为1。