什么是AOI机制? 为什么要用AOI:
所谓AOI 即 area of interest (感兴趣区域),在游戏中检测同步情况有时不需要显示全部人物以及障碍,比如游戏同时在线上万人,有人释放了技能 没必要所有人都需要接收到事件,只有感兴趣的条件部分环境需要接收。或者怪物自动追踪的距离设置 没必要所有怪物都会去追 只有在适合的位置,才会触发追踪。
所以我们需要管理玩家状态,寻找到玩家,也就需要坐标加范围的方式锁定玩家或障碍。
四叉树机制:
为什么要用四叉树?
是因为四叉树可以完整划分地图,方便 ,单次最多可排除百分之75的错误答案
四叉树是什么?
指树的每个节点下至多可以有四个子节点,通常把一部分二维空间细分为四个象限或区域并把该区域里的相关信息存入到四叉树节点中。这个区域可以是正方形、矩形或是任意形状。
首先把地图按四次分成不同的块,依次往下划分:
这就类似树的概念 可以一直往下延伸 直到可以发现目标在我们确定的某个子区域内
四叉树的属性:
1>.数据域 :Tree<T> 数据域对象
2>.关系域 :父节点 及 子节点指向
关系域包含 可以存放子节点的 数组或链表
依图可以找到游戏地图按区域划分的单元 我们选择的分几层 就是我们四叉树的深度取多深。至于究竟分多少层,看我们地图和目标的比例,合适即可。此刻我们引入管理。
关键在于:如果目标横跨我们当前分的所有分块的时候 我们就需要把目标放在上一层 即当前叶节点的父节点上。
附上代码 数据结构定义:
export class QuadTreeNode {
max_objects: number;
max_levels: number;
level: number;
bounds: any;
objects: Node[];
nodes: Quadtree[];
constructor(bounds, max_objects?, max_levels?, level?) {
this.max_objects = max_objects || 10;
this.max_levels = max_levels || 4;
this.level = level || 0;
this.bounds = bounds;
this.objects = [];
this.nodes = [];
}
insert(node: Node) {
let i = 0;
let indexes;
if (this.nodes.length) {
indexes = this.getIndex(node);
for (i = 0; i < indexes.length; i++) {
this.nodes[indexes[i]].insert(node);
}
return;
}
this.objects.push(node);
if (this.objects.length > this.max_objects && this.level < this.max_levels) {
for (i = 0; i < this.objects.length; i++) {
indexes = this.getIndex(this.objects[i]);
indexes.forEach((k) => {
this.nodes[k].insert(this.objects[i]);
});
}
this.objects = [];
}
}
};
小结:
后续我们通过得知目标存在的区域,通知此区域的碰撞盒,cocos或者unity自带的碰撞来高效做出检测和反应即可。