想象你住在幸福里社区。每天傍晚七点,六十位阿姨准时出现在中心广场,没有导演、没有对讲机,领舞李阿姨往台前一站,音乐响起,大家自动散开成方阵跳起来。神奇的是:没人喊“向左三步、向右两步”,队伍却始终整整齐齐;有人踩到水坑会绕开,有人掉队会小跑补位,队形变换丝毫不乱。她们靠的不是中央指挥,而是三条刻在肌肉记忆里的默契:别踩到旁边人的脚、跟着身边人的方向、别离人群太远。这种“让大量个体用极简规则自发形成有序集体”的思路,就是游戏开发中大名鼎鼎的群体AI(Swarm AI)。在《星际争霸》里框选两百个士兵一键推进,在塔防游戏里看着上千只怪物沿着多条道路涌向基地,背后正是这套“广场舞学问”:Boids 群集算法管“怎么聚成一群”,编队阵型管“站成什么形状”,流场寻路管“跟着地面的箭头走”,再配上空间哈希这类优化手段,让几百个单位在手机上也能跑出 60 帧。
对 AI 从业者而言,掌握群体AI与编队技术,意味着你能为 RTS、塔防、开放世界等大规模 NPC 场景设计出既高效又生动的集体行为,这是游戏 AI 工程师的核心竞争力之一。
目录
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
Boids三规则:分离(避免拥挤) + 对齐(速度同步) + 聚合(趋向中心) | 编队:槽位跟随+弹簧阻尼 | 流场:共享方向场+O(n)复杂度
群体AI概述:从“指挥千人”到“唤醒默契”
老式节日游行需要总导演拿着对讲机,逐个方阵下达指令,一旦台上的人喊错拍子,全场就乱套。幸福里舞团却完全不同——领舞李阿姨从不逐个人指挥,她只负责把动作跳标准,其余阿姨各自看着身边三五个人调整脚步。这就是群体AI(Swarm AI)的核心思想:放弃中央大脑,把智能下沉到每一个个体。
在游戏里,“对讲机总导演”对应的是传统的单智能体控制:每个 NPC 由行为树(Behavior Tree)或状态机精细驱动。当单位少,这很有效;可当单位多到几百上千,逐个指挥的成本会爆炸式增长,而且“整齐划一的集体感”极难用中央控制写出来——没人能给三百个士兵逐帧写脚本。群体AI 换了个思路:每个单位只感知邻居,执行几条简单规则,整体的行军、分散、包抄等复杂行为便自然涌现(Emergence)出来。
从数学上看,单位 i 最终受到的“合力”是它对邻域内所有邻居的交互函数之和:
就像阿姨们从不听总指挥、只观察身边几米的人,广场舞的整齐不是“管出来”的,而是“长出来”的。群体AI 的工程价值正在于此:用接近线性的算力,换来千军万马的生动秩序。
- 个体合力 $\mathbf{F}_i$单位 i 最终受到的推动力,是所有局部交互的总和,相当于阿姨感受到周围所有舞伴施加的“牵绊力”叠加。
- 邻域集合 $\mathcal{N}(i)$只统计感知半径内的邻居,远处的舞伴不影响你,这是“局部感知”的数学表达。
- 交互函数 $\phi$描述一对个体如何互相影响——靠太近要分开、方向偏离要修正等。
- 位置与速度 $\mathbf{p}, \mathbf{v}$交互只看对方“在哪里、往哪走”,信息完全局域,没有全局透视线。
Boids群集:广场舞的三条默契
1986 年,计算机图形学家 Craig Reynolds 发明了 Boids 算法,用来模拟鸟群、鱼群。他把复杂的群体行为拆成了三条极其简单的规则,恰好就是幸福里舞团阿姨们心照不宣的三条默契。Boids 这个单词念作“博伊兹”,取 Bird-oid(像鸟的东西)之意,如今是所有群体AI 教材的开篇第一课。
第一条默契叫分离(Separation):别踩到旁边人的脚。每个单位都会检查邻居,一旦有人靠得太近,就施加一个“推开”的力,让彼此保持最小距离。第二条叫对齐(Alignment):跟着身边人的方向。每个人把邻居们速度的平均方向当作参考,悄悄修正自己的朝向,于是整群人会朝同一个方向移动。第三条叫凝聚(Cohesion):别掉队。每个单位被拉向邻居们的“质心”——也就是人群的中心,谁落单了就会被群体“吸”回来。
三条力按权重叠加,就得到了每个单位的最终转向力:
Boids 的效果就像舞团阿姨们:没人发号施令,音乐一响,一群人自然而然地聚成一个流动的整体,忽而散开、忽而聚拢,却始终不散架。不过要注意,Boids 产生的是“液态”的松散集群,离“站成方阵”还差一步——那就要靠编队阵型了。
- 分离力 $\mathbf{F}_{sep}$方向由最近邻居指向自己,距离越近力越强,像阿姨慌忙往旁边挪半步。
- 对齐力 $\mathbf{F}_{align}$取邻域内所有舞伴速度的平均方向,帮助自己把朝向修正到集体方向。
- 凝聚力 $\mathbf{F}_{coh}$指向邻居质心的吸引力,把掉队的人拉回人群。
- 权重 $w_s, w_a, w_c$三条力的“话语权”,调大某一项就相当于改变整个团体的性格——分离权重高则松散,凝聚权重高则扎堆。
编队阵型:给每个位置发一张“站位卡”
舞团要在社区文艺汇演上表演,光靠三条默契只能跳成“一窝蜂”。于是李阿姨拿出一叠“站位卡”:每个人领到一张卡片,上面写着“第二排左边第三个”“第三排中间”——这就是编队阵型(Formation)的雏形。在游戏里,“站位卡”就是槽位偏移(Slot Offset),“李阿姨的位置”就是锚点(Anchor)。
阵型模板是一组槽位偏移的集合:方阵、圆阵、箭头阵、楔形阵,本质都是“相对锚点的坐标表”。每个单位每帧做两件事:先拿到锚点的世界坐标,再把自己的槽位偏移加上去,得到本帧应该站到的目标点。队伍转弯时,偏移坐标还要跟着锚点的朝向旋转,否则队伍就会“横着走”。
有了站位卡,舞团想换队形时,只需重新发卡——游戏里就是切换阵型模板,方阵瞬间变圆阵。但站位卡只回答了“该站哪”,还没回答“怎么站过去又不撞人”,这就轮到下一节出马了。
- 槽位目标点 $\mathbf{P}_{slot}$单位这一帧应该站到的世界坐标,即“站位卡”落地后的世界位置。
- 锚点位置 $\mathbf{P}_{anchor}$阵型的基准点,通常是领队单位或队伍质心的实时位置,全队都跟着它走。
- 旋转矩阵 $\mathbf{R}(\theta)$队伍整体转向角度 θ 时,偏移随之旋转,保证队形朝向与行进方向一致,就像阿姨转身时整排人跟着转向。
- 槽位偏移 $\mathbf{O}_{slot}$单位在队伍坐标系里的相对位置,阵型模板就是一张这样的偏移表。
阵型保持:站准位置,又不撞车
阿姨们拿到站位卡,目标点清清楚楚。但广场上不是真空的:前面有人挡路,旁边有人也在往自己的点走。如果每个人都“直线硬冲”自己的槽位,队伍还没站好就撞成一团。解决办法是把“归位”想象成一根看不见的弹簧:你偏离目标越远,弹簧拉你的力越大;同时弹簧还带着阻尼,防止你在目标点附近来回晃悠。
阵型保持的经典做法是 PD 控制(比例-微分控制),它产生一个“回拉力”:
弹簧模型让每个单位既能“站准”,又能“顺滑”。但现实总有不讲理的时候——正前方突然出现一个水坑,或者一辆电动车横穿广场。这时候“归队”得给“保命”让路,于是我们需要一套规则来决定:什么时候听谁的。
- 位置误差 $\mathbf{P}_{target} - \mathbf{P}_{unit}$当前站位与目标点的偏差,偏差越大,回拉力越大,就像弹簧拉得越长越用力。
- 位置增益 $k_p$弹簧的刚度,调大队伍更“整”但也更僵硬,调小则拖泥带水。
- 速度误差 $\mathbf{V}_{target} - \mathbf{V}_{unit}$目标点移动速度与单位速度的差,提供阻尼,避免单位带着惯性冲过目标。
- 阻尼系数 $k_d$控制“刹车力度”,防止阿姨在点周围前后抖动,参数过大过小都会让队伍看起来“神经质”。
流场寻路:地面画好箭头,跟着走
地铁站里,地面贴着花花绿绿的导流箭头:进站的、出站的、换乘的,人流浩荡却极少相撞,因为每个人只需低头看脚下的箭头,不必掏出手机重新规划路线。流场寻路(Flow Field Pathfinding)正是把这种智慧搬进了游戏:与其让几百个单位各自做 A* 寻路(等于人手一个导航仪),不如预先在整个地图上画好一张“箭头图”。
制作这张箭头图分两步。第一步,从目标点出发,像水波一样向外扩散,计算每个格子到达目标的代价场(Cost Field)——绕障碍多走一步,代价就高一点。第二步,站在每个格子上,环顾周围邻居,指向“代价最低的那个格子”的方向,就是这个格子的流场箭头。此后,任何单位走到某个格子,只需查表取箭头方向,跟着走即可。
流场最大的好处是共享:一千只怪物共用同一张箭头图,每帧只做一次查表,成本几乎可以忽略。如果某个目标点变化(比如塔防里老家换了位置),只需重新扩散一次代价场,所有怪物自动改道——相当于地铁站连夜重贴了一遍地面箭头。
- 代价场 $C(\mathbf{n})$每个格子存一个数,表示“从这里到目标要付出多大代价”,障碍越多代价越高,从目标点向外扩散计算。
- 邻居集合 $\mathcal{N}(\mathbf{x})$当前格子周围的 8 个相邻格子,查表只比较这几个。
- 最小代价邻居 $\mathbf{x}^{*}$在邻居里选出代价最低的那个,它是“下一步最划算”的方向。
- 归一化方向 $\mathbf{D}(\mathbf{x})$把“指向最佳邻居”的向量缩成单位长度,作为流场箭头存进格子。
行为融合:什么时候听谁的
阿姨们跳舞时,同时要“跟上队形”“避开洒水车”“踩准音乐节拍”,这些指令经常互相打架。如果她把三个方向的力平均一下,结果就是原地打转、寸步难行。游戏里的 NPC 更甚:避障力、队形力、流场力、攻击意图同时压过来,谁说了算?答案是优先级仲裁(Priority Arbitration)——危急时刻,低优先级行为直接让位。
最常见的策略是“安全距离门槛”:先看单位与最近障碍物的距离 d。如果 d 小于安全距离,说明马上要撞上了,此时只有避障力生效,其他一切靠后——先保命要紧。如果距离安全,再把队形力、流场力、墙体排斥力按权重混合相加。这种“分支 + 混合”的结构写出来就是:
优先级仲裁让群体在复杂环境中既灵活又整齐:平时队列一丝不苟,遇到突发状况立刻“化整为零”各自规避,危机解除又自动“化零为整”归队。这正是广场舞团让围观群众啧啧称奇的原因——她们从不硬挤,却也从未散场。
- 安全距离 $d_{safe}$触发避障的阈值,相当于“电动车距离我几米就该紧张”的警戒线。
- 危险分支 $\mathbf{V}_{avoid}$当 d 小于阈值,最终速度只由避障力决定,其余行为全部让位。
- 安全分支 $\mathbf{V}_{form} + \mathbf{V}_{flow} + \mathbf{V}_{wall}$距离安全时,队形力、流场力、墙体排斥力按权重线性混合,各司其职。
- 状态切换分支条件本身就是一个隐式的状态机,NPC 在“避障态”与“正常态”之间平滑切换。
性能优化:百人团的分片管理
如果舞团的默契规则要求“每个人每时每刻都要知道其他所有人的位置”,60 个阿姨就得互相喊话几千次,广场瞬间变成菜市场。程序里的朴素写法正是如此:N 个单位两两计算距离,复杂度是 O(N²)。300 个单位就要算 9 万次距离,再乘以每帧,性能直接崩溃。
程序员的对策叫空间哈希(Spatial Hashing):把地图切成一个个小格子,每个单位只登记进自己所在的格子;查询邻居时,只检查自己格子和周围相邻的 8 个格子,远处的人根本不用管。这就像广场被网格员分成片区,每个阿姨只需认识本片区的舞伴,不同片区互不干扰。
分片管理让 500 个单位的 Boids 模拟跑得动,远近分级让上千只怪物也不拖垮渲染管线。如果说 Boids 是“阿姨的个人修养”,空间哈希就是“网格员的分管制度”——群体AI 能走向工业化,靠的正是这种工程智慧。
- 朴素复杂度 $O(N^2)$每单位与其余 N-1 个单位都要算一次距离,总计算量随个体数平方增长。
- 空间哈希地图划分为网格,单位登记入格,查询只扫本格与相邻格,远处个体完全不参与计算。
- 平均邻居数 $\bar{k}$每个格子平均容纳的单位数,通常远小于 N,这是性能提升的关键变量。
- 细节分级(LOD)与批渲染远处怪群降低 AI 更新频率、用简模合批绘制,进一步把帧时间压到 60 帧以内。
实战案例:RTS 与塔防中的落地
舞团学成,终于要上台演出。但演出有两种风格:一种是国庆阅兵式的RTS 编队,追求排面整齐;另一种是春运车站式的塔防怪物潮,追求量大管饱。同样是群体AI,两套需求直接把参数调向了两个极端。
RTS 游戏(如《星际争霸》)里,玩家框选一两百个士兵,命令他们推进。玩家对“队形整齐度”极其敏感,所以这里用锚点跟随 + 队形保持:一个领队算全局路径,其余单位追各自的动态槽位,权重里队形力占大头,视觉上就是“一队人齐刷刷碾过去”。塔防游戏则相反,怪物上千只,没人关心它们站得整不整齐,只关心它们别卡在墙角。于是这里放弃精确编队,改用流场寻路:全场共享一张方向图,怪物各自查表前进,单位之间的避碰用很轻的分离力即可搞定。
两种需求的折中可以用一个混合式表达:
阅兵式要的是“整”,春运要的是“通”。同一条广场舞学问,换个舞台就换套参数——这正是群体AI 在真实项目中魅力所在:规则极简,调参极活,规模极大。
- 流场主导 $\mathbf{V}_{flow}$全局方向由流场提供,保证单位不迷路,这是所有方案的地基。
- 编队系数 $\lambda$RTS 中调大,队形紧凑像阅兵;塔防中调小甚至归零,队伍松散像潮水。
- 避障系数 $\mu$控制单位避让邻居与障碍的力度,调大则单位均匀铺开,调小则密集堆叠。
- 调参验证先跑通、再压性能、最后微调权重,观察“是否有抖动、是否卡位、是否散架”三个体检指标。
AI 应用场景
场景一:RTS 框选编队推进
阶段:单位决策与路径规划
解决的问题:传统做法让 200 个士兵各自独立寻路,不仅路径交叉拥堵,而且队形散乱、毫无“军队感”。AI 方案用“一个领队算路径 + 全员追槽位”:框选后领队做一次全局寻路(A* 或流场),其余单位通过队形保持力跟随各自的相对槽位,形成整齐方阵。
具体案例:《星际争霸 2》中框选一队机枪兵,命令它们穿过狭窄通道。领队选择绕行路线,其余单位通过阵型保持 + 避障融合,鱼贯通过通道后自动恢复矩形阵,全程无卡死。
场景二:塔防怪物洪流
阶段:大规模寻路与行为融合
解决的问题:上千只怪物如果各自 A* 寻路,CPU 直接爆掉。流场寻路把“逐单位计算”变成“全场预计算一次、所有单位查表”,再叠加轻量分离力防止怪物叠成一座山。
具体案例:《王国保卫战》式塔防中,怪物从多个入口涌向基地。地图预生成多张流场图,怪物按兵种选择不同流场,工程上只需每帧读取当前格子方向 + 施加分离力,即可支撑千级单位同时移动。
场景三:开放世界人群与动物群
阶段:群体行为模拟
解决的问题:开放世界的街道行人、草原兽群需要“活的”集体行为,又不能为每个个体写复杂逻辑。Boids 三规则 + 行为优先级融合,让 NPC 自然分流、结伴、避让,并配合 LOD 分级控制成本。
具体案例:某开放世界游戏中,城市广场刷出数百 NPC:他们自动沿着流场箭头逛街,遇到玩家坐骑会触发避障优先,坐骑离开后重新回归群体行为,观感自然且 CPU 占用极低。
Python 演示
import random import numpy as np class Boid: """一个广场舞单元:位置、速度、是否领舞。""" def __init__(self, pos, vel, is_leader=False): self.pos = np.array(pos, dtype=float) self.vel = np.array(vel, dtype=float) self.is_leader = is_leader def separation(boid, boids, radius=25.0): force = np.zeros(2) for other in boids: if other is boid: continue diff = boid.pos - other.pos dist = np.linalg.norm(diff) if 0 < dist < radius: force += diff / dist return force def alignment(boid, boids, radius=50.0): avg = np.zeros(2) count = 0 for other in boids: if other is boid: continue if np.linalg.norm(other.pos - boid.pos) < radius: avg += other.vel count += 1 if count > 0: avg /= count return avg - boid.vel return avg def cohesion(boid, boids, radius=60.0): center = np.zeros(2) count = 0 for other in boids: if other is boid: continue if np.linalg.norm(other.pos - boid.pos) < radius: center += other.pos count += 1 if count > 0: center /= count return center - boid.pos return center def seek(boid, target, speed=2.5): desired = target - boid.pos dist = np.linalg.norm(desired) if dist < 1e-6: return np.zeros(2) return desired / dist * speed - boid.vel def make_slots(rows, cols, spacing): slots = [] for r in range(rows): for c in range(cols): slots.append(np.array([ (c - cols / 2.0 + 0.5) * spacing, (r - rows / 2.0 + 0.5) * spacing, ])) return slots def update(boids, dt=0.1): for b in boids: force = 1.0 * separation(b, boids) force += 0.8 * alignment(b, boids) force += 0.4 * cohesion(b, boids) b.vel += force * dt speed = np.linalg.norm(b.vel) if speed > 4.0: b.vel *= 4.0 / speed b.pos += b.vel * dt b.pos %= 500.0 def main(): random.seed(7) boids = [ Boid([random.uniform(200, 300), random.uniform(200, 300)], [random.uniform(-1, 1), random.uniform(-1, 1)]) for _ in range(45) ] boids[0].is_leader = True slots = make_slots(rows=3, cols=14, spacing=16.0) anchor = np.array([400.0, 250.0]) for frame in range(120): update(boids) boids[0].vel += seek(boids[0], anchor) * 0.1 for unit, slot in zip(boids[1:], slots): target = anchor + slot unit.vel += seek(unit, target) * 0.08 if frame % 20 == 0: leader = boids[0] dists = [np.linalg.norm(u.pos - leader.pos) for u in boids] print("frame", frame, "leader", leader.pos.round(1), "avg_dist", round(sum(dists) / len(dists), 1)) if __name__ == "__main__": main()
force = 1.0 * separation(b, boids)分离力权重 1.0,保证单位不会互相重叠。force += 0.8 * alignment(b, boids)对齐力权重 0.8,让群体朝一致方向移动。force += 0.4 * cohesion(b, boids)凝聚力权重 0.4,防止个体掉队。if speed > 4.0: b.vel *= 4.0 / speed限制最大速度,模拟单位移动上限。b.pos %= 500.0环形世界:走出边界就从对面回来,省去边界碰撞处理。boids[0].vel += seek(boids[0], anchor) * 0.1领舞被引向锚点,作为全队的移动基准。slots = make_slots(rows=3, cols=14, spacing=16.0)生成 3×14 的矩形阵型槽位表。target = anchor + slot每个单位的目标点 = 锚点 + 自己的槽位偏移(站位卡)。unit.vel += seek(unit, target) * 0.08跟随单位向自己的槽位点靠近,形成编队。dists = [np.linalg.norm(u.pos - leader.pos) for u in boids]统计全体与领舞的平均距离,观察编队收敛程度。
常见误区
误区单位越多,行为树就越丰富。把行为树、状态机复制几百份,不就是一个“群体”了吗?每个 NPC 都需要详细的逻辑才能显得智能。
正解行为树适合“小而精”的个体智能,单个单位可以写几百行逻辑;当单位达到数百上千,每帧遍历所有行为树状态机的开销会爆炸,而且用中央脚本很难写出“同一方向齐步走”的集体感。群体AI 把智能下沉到 3~5 条局部规则,用交互涌现队形,算力近似线性。类比:行为树是教练对每个运动员单独指导,群体AI 是阿姨们自己看身边人——效率天差地别。
为何常见:多数教程先教行为树,容易形成思维定势,认为“更智能 = 更多逻辑”,忽略了“局部规则 + 涌现”这条完全不同的路径。
误区把分离、对齐、凝聚的权重调一调,Boids 就能走出方阵、圆阵、箭头阵,毕竟演示视频里它们看起来那么整齐。
正解Boids 产生的是“液态”的松散集群(像鸟群、鱼群),不是“固态”的严格编队。要形成方阵、圆阵、箭头,必须显式定义槽位偏移和锚点,让每个单位“追自己的站位卡”。Boids 管“聚得自然”,编队管“站得整齐”,两者是叠加的两层系统。类比:三条默契只保证大家不撞车、不掉队,但谁站哪个点,还得靠站位卡。
为何常见:Boids 演示里单位确实“成群结队”,外观看上去就是队形,容易误以为松散集群等于严格编队。
误区流场寻路无非是 A* 的加速版,本质还是每个单位独立规划一条路径,只是跑得快一点。
正解恰恰相反。流场寻路把“算路径”从单位身上整体剥离:预先(或低频)从目标点向全地图扩散生成代价场,再为每格存一个“指向低代价邻居”的方向;单位每帧只做一次查表,成本是 O(1) 级别的。逐单位 A* 是“每个人开车时现开导航”,流场是“地铁站提前贴好地面箭头”。
为何常见:习惯了逐单位寻路的实现思路,难以理解“先算一张全场图,再让所有单位共享”这种逆向设计。
误区把避障、队形、寻路、攻击意图全部加权叠加,行为越多越丰富,NPC 自然更聪明。
正解多行为线性叠加会互相“拔河”:队形力拉左,避障力拉右,寻路力拉前,最终单位原地抖动或绕圈。工程上普遍用优先级仲裁——先用安全距离判断是否触发避障,高优先级行为独占,低优先级让位;即使混合,也要保证某一项在局部占主导。类比:阿姨遇到洒水车时,绝不会同时执行“跟上队形”和“避开洒水车”。
为何常见:“叠加”在直觉上很自然,但忽略了不同力的方向冲突,以及“同时服从所有指令=原地不动”的现实。
误区空间哈希提速全靠格子小,格子切得越细,每格单位越少,查询越快,索性把格子切成像素级。
正解格子尺寸必须和感知半径匹配:查 3×3 邻域时,格子边长至少是感知半径的 2 倍,才能保证所有真邻居都落在相邻格里。格子过小会导致真正邻居被漏掉,单位“看不见”身边人,群体瞬间散架;格子过大则每格单位太多,退化回 O(N²)。哈希只是把“全局扫描”变成“局部扫描”,正确率与格尺寸强绑定。
为何常见:直觉认为“粒度越细越精确”,忽略了邻域覆盖对格子尺寸的下限约束,属于典型的过度优化。
面试题
Q1. Boids 算法的三条基本规则是哪三条?
- A.攻击、防守、巡逻规则
- B.搜索、追逐、撤退规则
- C.分离、对齐与凝聚规则← 正确答案
- D.加速、减速与转向规则
答案:C。Boids 的三规则是分离(别踩脚)、对齐(跟方向)、凝聚(别掉队),对应答案 C。A 和 B 是战斗行为,D 是运动学控制,都不属于群体规则层面。
Q2. 群体AI 相比“每个单位一套行为树”的核心优势是什么?
- A.大规模单位算力更低← 正确答案
- B.每个单位行为更复杂
- C.完全无需导航网格支持
- D.完全不需要任何参数调优
答案:A。群体AI 用少量局部规则替代海量个体逻辑,计算量与个体数近似线性增长,适合大规模 NPC。B 恰恰相反,行为树个体逻辑更重;C、D 说法绝对化,群体AI 仍需导航与调参。
Q3. 编队阵型中“槽位(Slot)”指的是什么?
- A.地图上刷怪的固定出生点
- B.相对锚点的队形相对坐标← 正确答案
- C.单位自带的朝向角度数值
- D.领队单位自身血量上限值
答案:B。槽位是单位在队伍坐标系中的相对位置,即“站位卡”,世界坐标 = 锚点 + 槽位偏移。A 是刷怪点概念,C 是朝向,D 是属性,都与编队坐标无关。
Q4. 流场寻路中,每个格子通常存储什么数据?
- A.一条完整的最优路径信息
- B.地图格子的地形高度值
- C.指向低代价格子的方向← 正确答案
- D.单位当前位置的坐标值
答案:C。流场每个格子存的是“推荐移动方向”,来自代价场的梯度。A 是逐单位路径,B 是地形数据,D 是单位属性,都不是流场内容。
Q5. 空间哈希查询邻居时,需要检查哪些格子?
- A.遍历整个地图的所有格子
- B.本格与周围相邻的格子内← 正确答案
- C.只检查距离最近的单个格子
- D.只检查同阵营单位的格子
答案:B。空间哈希把单位登记进所在格,查询邻居只需扫描本格和相邻的 8 个格子,前提是格子尺寸匹配感知半径。A 退化为暴力遍历,C、D 都会漏掉真实邻居。
Q6. 单位同时收到避障力与队形力且方向冲突时,常见仲裁策略是?
- A.两力直接取算术平均
- B.安全距离内避障有限优先← 正确答案
- C.队形力永远大于避障力
- D.每帧随机选择一种力执行
答案:B。工程上普遍采用优先级仲裁:距离小于安全阈值时避障独占,否则才混合队形力等。A 会导致原地抖动,C 会撞上障碍,D 随机性不可控。
Q7. 以下哪些属于流场寻路的特点?
- A.支持上千单位同时寻路← 正确答案
- B.全场单位共享一张方向图← 正确答案
- C.每个单位独立计算最短 A*
- D.代价场可融入地形权重← 正确答案
答案:ABD。流场的核心是“全场共享一张方向图”,单位查表即可,天然支持海量单位;代价场可以加权地形、威胁区。C 是逐单位 A* 的思路,与流场相反。
Q8. 提升大规模 NPC 群体AI 性能的常用手段有哪些?
- A.空间哈希加速邻居查询← 正确答案
- B.远处单位降低更新频率← 正确答案
- C.全员改用更高精细模型
- D.合批绘制减少调用次数← 正确答案
答案:ABD。空间哈希把邻居查询从 O(N²) 降到近似线性;LOD 降频和渲染合批都是标准优化手段。C 高精模型反而增加渲染负担,方向完全错误。
Q9. 群体AI 中所说的“涌现”指的是什么?
- A.预设写死每个个体的全部动作
- B.局部规则交互产生宏观集体行为← 正确答案
- C.在线学习自动生成角色动画
- D.游戏引擎随机生成地图地形
答案:B。涌现指大量个体按简单局部规则交互,整体出现无人预设的复杂集体行为,如鸟群转向、鱼群散开。A 是中央控制,C 是机器学习,D 是程序化生成。
Q10. 关于编队保持的 PD 控制,以下说法正确的有哪些?
- A.位置误差越大回拉力度越强← 正确答案
- B.速度项提供阻尼防止抖动← 正确答案
- C.增益系数越大效果必然越好
- D.可再叠加避障力做局部修正← 正确答案
答案:ABD。PD 控制中位置误差产生回拉力,速度差提供阻尼防振荡,并可叠加避障力做优先级混合。C 错误:增益过大会导致振荡甚至发散,并非越大越好。