鸿蒙游戏AI行为驱动系统

作者:技术拾光时间:2026-06-15 06:32:07浏览:366

核心问题:为什么不能把AI决策直接写进BattleSystem?当你在鸿蒙游戏里把架构拆成 Store、System、Engine、UI 这套东西后,处理玩家行为通常是顺滑的:点击按钮 → 触发System → 更新状态。但一旦你开始琢磨NPC行为、敌人决策、自动战斗、动态难度这些玩意儿,事情就变得

核心问题:为什么不能把AI决策直接写进BattleSystem?

当你在鸿蒙游戏里把架构拆成 Store、System、Engine、UI 这套东西后,处理玩家行为通常是顺滑的:点击按钮 → 触发System → 更新状态。但一旦你开始琢磨NPC行为、敌人决策、自动战斗、动态难度这些玩意儿,事情就变得棘手了。

很多人第一反应就是:嗨,这不就是一堆 if-else 吗?直接往 BattleSystem 里写,或者干脆塞进UI层的逻辑里。结果呢,用不了多久,代码就乱成了一锅粥,行为变得不可控,想加点新东西更是难上加难。所以,我们要解决的核心问题,就是如何优雅地引入“智能”。关键在于建立一套独立的、行之有效的决策系统。

看看这个典型的反面教材:

class BattleSystem {
  update(store: GameStore) {
    // 玩家逻辑
    this.handlePlayer(store)
    // AI逻辑
    if (store.enemyHp < 30) {
      this.escape()
    } else {
      this.attack()
    }
  }
}

问题非常明显:规则(怎么计算伤害、处理冷却)和决策(什么时候攻击、什么时候逃跑)被硬生生搅合在一起了。 这就好比你把厨房和餐厅混在一起,做饭和吃饭都在同一个地方,肯定会乱。这带来的直接后果就是AI逻辑无法复用,行为很难扩展,系统也变得脆弱。你改一个地方的决策,很可能就影响了另一个地方的规则。

一个关键拆分:规则 vs. 决策

你必须把这两件事彻底分开。游戏世界里,有两种截然不同的逻辑。

  • System(系统): 回答“如何做”的问题。攻击怎么计算?伤害怎么生效?冷却时间怎么处理?这些是游戏世界的铁律,是客观规则。
  • AISystem(AI系统): 回答“做什么”的问题。什么时候攻击?什么时候逃跑?选择哪个技能?这些是基于当前状态做出的主观判断,是智能决策。

一句话总结就是:系统决定世界怎么运转,AI决定角色怎么选择。

AISystem的核心职责

AISystem的本分很明确,它有三不碰:

  • 不直接修改Store(状态)。 它只读数据,不写数据。
  • 不写具体的游戏规则。 它不关心攻击力计算,也不管技能冷却。
  • 不控制执行流程。 它只负责给出一个“想法”(Action),具体怎么执行,那是System的事。

它唯一要做的一件事,就是根据当前状态,输出一个行为指令。

AISystem的最小模型

一个最朴素的AISystem,其实就是一个决策函数:

export class AISystem {
  decide(store: GameStore): Action {
    if (store.enemyHp < 30) {
      return { type: "ESCAPE" }
    }
    return { type: "ATTACK" }
  }
}

然后,由另一个系统(比如 BattleSystem)来执行这个决策结果:

const action = ai.decide(store)
battleSystem.execute(store, action)

从“if-else”到“行为模型”

初学者的写法是直接写死条件判断:

if (hp < 30) run()
else attack()

但进阶之后,你会希望将它构造成一个清晰的行为模型:

  1. 行为枚举(ActionType): 定义游戏里所有可能的AI行为。
  2. 行为选择器(Decide): 实现具体的决策逻辑,输出一个行为类型。
  3. 行为执行器(Execute): 根据决策结果,调用具体的System规则来执行。

这样拆开的好处是立竿见影的:结构清晰,易于扩展(加个新行为只需改枚举和选择器),并且方便单独测试(可以只测试决策逻辑)。

AISystem的三种进阶模式

根据游戏的复杂度和需求,AISystem可以有不同的实现模式:

  1. 规则驱动(Rule-Based): 最直接的方式,纯 if-else。简单可控,适合基础AI,比如小怪。
  2. 权重驱动(Weighted Scoring): 给每个行为打分,选择分数最高的。比如攻击得0.7分,逃跑得0.9分,那AI就会选择逃跑。这种方式更灵活,能平滑地调节AI的倾向性。
  3. 模型驱动(Model-Driven): 通过调用机器学习模型来做决策。最灵活、最智能,但也最不可预测,适合Boss或特殊NPC。

AISystem与System的协作关系

记住这个核心原则:AISystem只决策,System只执行。

错误的做法是:

// 错误:AI直接修改状态
ai.decide(store) // 内部直接 store.hp -= 10

正确的协作方式应该是:

const action = ai.decide(store)   // AI输出 Action
engine.dispatch(action)           // 调度器分发 Action

引入“行为调度层(AIEngine)”

当游戏里有多个AI实体(比如多个敌人、队友)时,你不能简单地一个 ai.decide() 搞定。你需要一个统一的调度器:

class AIEngine {
  aiSystems: AISystem[] = []
  run(store) {
    return this.aiSystems.map(ai => ai.decide(store))
  }
}

这个调度层的作用很关键:统一所有AI的执行,支持多AI并行决策,并且让系统更容易组合和扩展。

避免AI失控的关键机制

AI一旦复杂起来,就很容易“发疯”。你必须加上几层保护:

  1. 约束: AI不能无视硬性规则。比如角色被眩晕了,它就不能做任何事。
  2. 校验: AI决策出来的Action是否合法?比如角色MP不够,它就不能释放了一个需要消耗MP的技能。
  3. 优先级: 当AI同时想干好几件事时,必须有明确的优先级。比如逃跑永远比攻击重要。

AISystem在多端中的作用

在多人协同或跨设备同步的场景下,AI决策必须统一。如果每个设备各算各的AI,结果必然导致状态漂移。

正确的做法是:在权威端(Host)运行AI,其他设备同步决策结果。 这样可以保证所有玩家看到的游戏世界是一致的。

一个关键认知升级

初学者会觉得:AI = 一段逻辑。但当你真正理解了这个架构后,你会知道:AI = 一个独立的决策层,它是一个输入(状态) → 输出(行为)的函数。

整个游戏运行流程就变成了:

状态(Store)
   ↓
AISystem(决策)
   ↓ Action
System(执行)
   ↓
状态变化(回到第一步)

最终架构

最后,一个理想的鸿蒙游戏AI架构应该像这样:

  • Store:存放所有游戏状态。
  • AIEngine & AISystem(s):负责从Store读取数据,并输出所有实体的Action列表。
  • System(s):接收Action,执行具体的游戏规则,并更新Store。
  • Engine:负责整个流程的调度。
  • UI:从Store读取数据,渲染画面。

总结

在鸿蒙游戏开发中,你需要清晰地划分两个角色:

  • System:定义游戏世界的规则。
  • AISystem:决定游戏角色的行为。

两者缺一不可。当你能真正用好 AISystem,你的游戏就会从一个“写死的逻辑”进化为一个“拥有生命的系统”。这才是游戏变得真正有趣和复杂的关键所在。