Skip to content

性能优化

案例

SLG 游戏(大地图,多单位)

  • 空间分割:对于大型地图,使用四叉树、八叉树或 BSP(二叉空间分割)树来管理空间和对象可以有效减少需要处理的单位数量,特别是在视野裁剪和碰撞检测中。
  • 按需加载和卸载:不是一次性加载整个地图和所有单位,而是根据玩家的视野和位置动态加载周边区域的资源。
    • 资源共享、对象池等复用
    • 后台数据处理、异步加载、并行处理
    • 视野加载(进入视野再加载),根据位置和移动速度进行预测,动态加载和卸载
    • 事件触发加载(结合空间分割)
    • 分级加载(地图缩放不同,加载数据量不同)
  • 网络优化
    • 状态压缩(减少数据包大小)
    • 增量更新
    • 预测与差值
  • 渲染优化
    • 分级渲染(远处的渲染细节低)
    • 视野剔除(不渲染视野之外)
    • 批处理渲染
  • UI 优化
    • 合并绘制,减少渲染开销
    • 动态更新,数据变化 ui 才变化
  • 事件驱动模型:
    • 适用于需要处理大量实体和交互的游戏:基于事件的响应,而不是在每一帧中轮询所有对象的状态。这可以显著减少不必要的计算,提高游戏的性能和响应速度。
    • 定义事件:首先,需要定义可能发生的事件类型。这些事件可以包括用户输入、游戏逻辑触发的事件(如单位死亡、资源耗尽)、定时事件等。(首先定义触发攻击检查的事件,例如“敌人进入范围”或“单位被选中为攻击目标”,而不是每一帧进行检查)
    • 注册监听器:各个游戏组件注册对特定事件的监听。当这些事件被触发时,只有注册了监听的组件才会响应并处理这些事件。
    • 事件队列:游戏维护一个事件队列,所有发生的事件都首先被放入这个队列。每一帧,游戏循环都会处理这个队列中的事件,并调用相应的事件处理器。
    • 处理事件:当事件被处理时,相关的游戏逻辑被执行,如移动单位、更改游戏状态或更新用户界面。

      对比-传统模型

    • 持续检查:每个对象需要在每一帧中检查是否满足攻击条件。这包括计算距离、可能的目标检查和其他条件。
    • 重复计算:如果游戏中有很多对象,这种方法会导致大量的重复计算和资源浪费,特别是当大部分时间这些检查的结果是“不攻击”时。
  • 使用事件驱动重构移动
    • 事件定义:
      • 敌人检测事件:当敌人单位进入某个士兵的感知范围时触发。
      • 移动命令事件:玩家通过 UI 发出移动命令时触发。
    • 事件监听:
      • 对于敌人检测事件,监听器负责检测周围是否有敌人单位进入感知范围。
      • 对于移动命令事件,监听器负责接收玩家的移动指令。
    • 处理敌人检测事件
      • 自动追踪:当敌人单位被检测到时,如果士兵当前没有其他更高优先级的行为(如手动移动命令),自动计算路径并移动向该敌人单位。
      • 持续更新:如果敌人单位移动,更新追踪路径。可以通过连续触发的敌人位置更新事件来实现。
    • 处理移动命令事件
      • 路径计算:接收到移动命令后,立即计算从当前位置到目标位置的最优路径。
      • 行为覆盖:手动命令应该有更高的优先级,能够覆盖自动追踪敌人的行为。确保在接收到新的移动命令时,取消或暂停当前的追踪状态。