游戏系统组件——游戏逻辑有哪些组件
一句话
游戏系统(引擎之上的游戏逻辑)包含的组件,和引擎子系统在「组件化」层面没有区别——都是数据 + 算法 + 接口的组合。区别只是:游戏组件实现具体游戏,引擎组件支撑游戏。
一、游戏系统可能包含的组件
1 2 3 4 5 6 7 8 9 10
| 游戏系统可能包含的组件: ├── 玩家控制组件 ← 输入映射、角色控制、相机跟随 ├── AI 组件 ← 寻路、状态机、行为树 ├── 战斗组件 ← 攻击判定、伤害计算、Buff 系统 ├── 物品组件 ← 背包、装备、使用、掉落 ├── 关卡组件 ← 关卡加载、触发器、脚本事件 ├── 对话组件 ← 对话树、选项、分支 ├── 存档组件 ← 保存、加载、序列化 ├── UI 组件 ← HUD、菜单、对话框 └── 音效组件 ← 环境音、技能音效、BGM
|
二、System ≈ Service:一个 System 内部其实也是分层的
这是 ECS 最容易混淆的地方——System 不是算法层,System 更像「业务流程层(Service)」,算法层只是它调用的一部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| MovementSystem::Update() { auto entities = registry.View<Transform, Velocity>();
for (...) { PhysicsAlgorithm::Integrate();
PhysicsWorld::Move();
transform.position = ...; } }
|
这里其实已经有三层:
1 2 3 4 5
| MovementSystem │ ├── Component(数据) ├── Algorithm(计算) └── Engine API(底层)
|
桌面软件与 ECS 游戏的对应
| 桌面软件 |
ECS 游戏 |
| 数据层 |
Component |
| 算法层 |
PathFinding、Collision、Animation 算法等 |
| 原子接口 |
Renderer、Physics、Input、Audio 等底层接口 |
| API / Service |
System |
| GUI |
游戏 UI |
| 主程序 |
Game Loop |
三、整个游戏工程也应该像桌面软件一样分层
1 2 3 4 5 6 7 8 9 10 11
| Game/ ├── game/ ← 游戏业务层 ├── ecs/ ← 数据组织 ├── renderer/ ← 渲染模块 ├── physics/ ← 物理模块 ├── input/ ← 输入模块 ├── resource/ ← 资源模块 ├── audio/ ← 声音模块 ├── scene/ ← 场景管理 ├── infrastructure/ ← 日志、线程、事件 └── platform/ ← SDL/Win32/OpenGL
|
四、组件 × 算法 × 接口 = 游戏能力
用「功能函数 = 数据结构 + 算法 + 接口」的模型理解游戏:
1 2 3 4 5 6 7 8 9
| 游戏规则分析 ↓ Component(数据)/ 算法 / Engine API(原子接口) ↓ System(业务) ↓ Scene ↓ Game Loop
|
例如战斗:
1 2 3 4
| CombatSystem(业务) ├── HealthComponent / AttackComponent(数据) ├── DamageAlgorithm(算法:攻击-防御、暴击判定、属性克制) └── Engine API(接口:碰撞查询、事件广播、动画触发)
|
五、需要回答的问题
- 游戏组件和引擎子系统的边界在哪?——组件调用引擎能力,引擎不依赖游戏组件(单向依赖)
- 组件之间的数据怎么共享?——ECS 的 Component?Entity-Component 模式?(见游戏系统组件组装线)
- 组件的异常处理: AI 寻路失败怎么处理?存档损坏怎么恢复?
与其他线的关系
- 与引擎组装线:引擎是支撑子系统,游戏组件是业务子系统——本线讲游戏这边有什么组件
- 与游戏系统组件组装线:本线讲「有什么组件」,组装线讲「组件怎么拼成游戏」
- 与单一职责主题:每个 Component 只有数据、每个 System 只有一个职责——单一职责在游戏层的应用
- 与从指令到系统主线:组件 = 数据 + 算法 + 接口 的模型直接继承自主线「功能函数 = 数据结构 + 算法 + 接口」