chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,332 @@
# 03 · 玩家系统规范
> **所属文档集** [← 返回索引](./README.md)
> **摘要**:玩家实体的构成、资源模型、状态机规范与对外行为契约。
> **关联**[04_CombatSystem](./04_CombatSystem.md) · [05_MovementSystem](./05_MovementSystem.md) · [06_FormSystem](./06_FormSystem.md)
---
## 目录
1. [玩家实体构成](#1-玩家实体构成)
2. [资源模型](#2-资源模型)
3. [玩家状态机](#3-玩家状态机)
4. [行为契约](#4-行为契约)
5. [能力解锁体系](#5-能力解锁体系)
6. [玩家配置参数](#6-玩家配置参数)
7. [发出的事件](#7-发出的事件)
---
## 1. 玩家实体构成
玩家实体是多个**职责分离的子系统**的协调器,自身不含具体业务逻辑:
```
PlayerEntity协调器
├── MovementController ← 物理移动(速度、跳跃、冲刺)
├── StatContainer ← 资源数值HP、灵力、魄元、灵泉、Geo
├── CombatHandler ← 攻击判定HitBox 开关、连击链)
├── FormController ← 形态管理(天魂/地魂/命魂切换)
├── WeaponSlot ← 当前武器(形态联动自动切换)
├── SkillExecutor ← 技能执行(魂技能/魄技能)
├── ParryHandler ← 弹反逻辑
├── HurtBox ← 受击判定(路由 DamagePacket
└── StateMachine ← 行为状态机(协调上述子系统)
```
**协调器原则**PlayerEntity 只负责:
1. 初始化子系统并维护引用
2. 维护状态机(决定当前行为)
3. 在受击时强制转换到受击状态
4. 在死亡时触发 `OnPlayerDied` 事件
---
## 2. 资源模型
### 2.1 资源总览
| 资源 | 类型 | 范围 | 特性 | 用途 |
|------|------|------|------|------|
| **HP** | Integer | 0 ~ MaxHP | 受击减少,存档点/灵泉恢复 | 生存指标 |
| **灵力SoulPower** | Integer | 0 ~ 100 | 近战命中积累,死亡清零 | 魂技能燃料 |
| **魄元SpiritPower** | Integer | 0 ~ 100 | 时间自动恢复,死亡恢复至上限 | 魄技能燃料 |
| **灵泉次数SpringCharges** | Integer | 0 ~ MaxCharges | 击杀积分驱动,存档点恢复 | 治疗次数 |
| **Geo灵晶** | Integer | 0 ~ ∞ | 击败敌人获得,死亡遗留遗骸 | 货币 |
### 2.2 灵力积累规则
> **设计目标**:鼓励玩家主动攻击,弹反作为高回报行为
| 来源 | 灵力增量 |
|------|---------|
| 近战命中普通敌人 | +10 |
| 近战命中 Boss | +5 |
| 弹反成功 | +33 |
- 死亡时归零
- 无自动恢复
### 2.3 魄元恢复规则
> **设计目标**:魄元是始终可用的"持续消耗"资源,不依赖风险操作
| 来源 | 魄元增量 |
|------|---------|
| 每秒自动恢复 | +`spiritRegenRate`(见配置参数)|
| 死亡复活 | 恢复至上限 |
| 存档点交互 | 恢复至上限 |
- 受伤不影响魄元
- 使用魄技能后扣除固定量
### 2.4 灵泉次数规则
> **设计目标**:治疗是"击杀驱动"而非"时间驱动",鼓励激进战斗风格
| 来源 | 变化 |
|------|------|
| 击杀普通敌人 | +1 积分 |
| 击杀精英怪 | +3 积分 |
| 击杀 Boss | +5 积分 |
| 积分达到阈值 | +1 次灵泉(积分清零)|
| 使用灵泉(治疗)| -1 次 |
| 与存档点交互 | 恢复至上限 |
| 死亡复活 | **不恢复**(死亡惩罚)|
> **设计决策**:死亡不恢复灵泉
> **原因**:保留一定死亡惩罚,让玩家珍惜治疗机会,但由于复活在存档点旁,玩家仍可快速通过激活存档点补满
### 2.5 Geo货币规则
| 来源 | 变化 |
|------|------|
| 击败敌人 | 掉落固定 + 随机范围 |
| 破坏场景容器 | 少量固定 |
| 任务奖励 | 固定量 |
| 死亡 | Geo 留在遗骸,不直接丢失 |
| 取回遗骸 | 遗骸的 Geo 归还玩家 |
| 再次死亡(未取回遗骸)| 遗骸 Geo **永久丢失** |
---
## 3. 玩家状态机
### 3.1 状态优先级
| 优先级 | 状态 | 说明 |
|--------|------|------|
| 100 | `DeathState` | 死亡,不可被任何状态打断 |
| 90 | `HurtState` | 受击硬直,仅死亡可打断 |
| 80 | `DashState` | 冲刺(含空中冲刺),受伤/死亡可打断 |
| 75 | `SoulSkillState` | 魂技能前摇,冲刺/受伤可打断 |
| 72 | `SpiritSkillState` | 魄技能前摇,冲刺/受伤可打断 |
| 70 | `ParryState` | 弹反等待,受伤可打断 |
| 60 | `AttackState` | 攻击,弹反/受伤可打断 |
| 55 | `SpringState` | 使用灵泉,前摇可被打断 |
| 40 | `InteractState` | 与 NPC/物件交互 |
| 35 | `WallGrabState` | 抓墙悬挂,冲刺/技能可打断 |
| 30 | `AirState` | 空中(含跳跃/下落)|
| 20 | `RunState` | 地面奔跑 |
| 10 | `SwimState` | 游泳(解锁后)|
| 0 | `IdleState` | 待机(最低优先级)|
### 3.2 状态转换规则
```
任意状态
══受击(HP>0)══► HurtState [强制,忽略优先级]
══受击(HP=0)══► DeathState [强制,不可被打断]
IdleState
──移动输入──────────► RunState
──跳跃输入──────────► AirState
──攻击输入──────────► AttackState
──弹反输入──────────► ParryState
──冲刺输入──────────► DashState
──魂技能+灵力充足───► SoulSkillState
──魄技能+魄元充足───► SpiritSkillState
──使用灵泉+次数≥1──► SpringState
──交互输入+目标存在─► InteractState
RunState
──无移动输入─────────► IdleState
──跳跃输入───────────► AirState
──攻击输入───────────► AttackState保持RunState上半身叠加
──弹反/冲刺/技能─────► 对应状态
AirState统一处理 跳跃/双跳/下落)
──落地───────────────► IdleState 或 RunState
──跳跃输入+双跳可用──► AirState内重置双跳不切状态
──贴墙+朝墙方向输入──► WallGrabState
──攻击/弹反/冲刺─────► 对应状态
WallGrabState
──跳跃输入───────────► AirState蹬墙跳
──反向输入或落地─────► AirState / IdleState
──冲刺/技能──────────► 对应状态
AttackState上半身叠加下半身保持原状态
~~动画结束~~──────────► 恢复原状态Idle/Run/Air
──连击窗口内攻击输入─► AttackState切换连击段
──弹反输入───────────► ParryState
ParryState
──弹反成功───────────► ParrySuccessState反击窗口
──攻击输入(窗口内)─► AttackStateParryCounter
~~反击窗口超时~~─────► IdleState/RunState
~~弹反超时~~──────────► IdleState/RunState
DashState
~~冲刺时长结束~~────── ► AirState 或 IdleState/RunState
SpringState
~~前摇完成~~──────────► 后摇 → IdleState
──被打断─────────────► IdleState灵泉次数已扣不返还
HurtState
~~硬直时长结束~~──────► IdleState
DeathState
(等待游戏管理器触发复活流程)
```
### 3.3 攻击连击链
| 连击段 | 触发方式 | 攻击方向 | 伤害倍率 | 备注 |
|--------|---------|---------|---------|------|
| `Attack1` | 第一次攻击输入 | 水平 | ×1.0 | 各形态动画不同 |
| `Attack2` | 连击窗口内再攻击 | 水平 | ×1.0 | |
| `Attack3` | 连击窗口内再攻击 | 水平 | ×2.0 | 重击,连击链结尾 |
| `AirAttack` | 空中攻击 | 水平 | ×1.0 | |
| `UpAttack` | 移动方向向上时攻击 | 向上 | ×1.0 | 角色轻微下移(反作用力)|
| `DownAttack` | 空中+移动方向向下时攻击 | 向下 | ×1.0 | 命中时产生弹起Pogo|
| `ParryCounter` | 弹反成功后攻击 | 水平 | ×3.0 | 不可被弹反,忽略无敌帧 |
> **设计决策**:第三击伤害 ×2弹反反击 ×3
> **原因**:鼓励打满连击,奖励弹反技巧。高倍率使玩家有显著的策略目标。
---
## 4. 行为契约
### 4.1 玩家实体对外接口
```
Interface IPlayerEntity {
// 只读属性
[readonly] position : Vector2
[readonly] facingDirection : Integer // +1 右 / -1 左
[readonly] currentState : StateID
[readonly] isInvincible : Boolean
// 强制状态切换(外部系统使用,如受击)
forceState(stateId: StateID, context: Optional<StateContext>) → void
// 查询
hasAbility(abilityId: ID) → Boolean
// 事件
[event] onDied : Event<void>
[event] onHit : Event<HitPayload>
[event] onStateChanged : Event<StateChangedPayload>
}
```
### 4.2 StatContainer 对外接口
```
Interface IStatContainer {
[readonly] currentHP : Integer
[readonly] maxHP : Integer
[readonly] currentSoulPower : Integer
[readonly] currentSpiritPower : Integer
[readonly] currentSpringCharges: Integer
[readonly] maxSpringCharges : Integer
[readonly] currentGeo : Integer
[readonly] isAlive : Boolean
takeDamage(amount: Integer) → void
heal(amount: Integer) → void
addSoulPower(amount: Integer) → void
consumeSoulPower(amount: Integer) → Result<Boolean>
consumeSpiritPower(amount: Integer) → Result<Boolean>
addKillCredit(creditType: KillType) → void // 驱动灵泉积分
useSpring() → Result<Boolean>
restoreSpringCharges() → void
addGeo(amount: Integer) → void
spendGeo(amount: Integer) → Result<Boolean>
beginInvincibility(duration: Duration)→ void
[event] onHPChanged : Event<{current, max}>
[event] onSoulPowerChanged : Event<{current, max}>
[event] onSpiritPowerChanged : Event<{current, max}>
[event] onSpringChargesChanged : Event<{current, max}>
[event] onGeoChanged : Event<{current, delta}>
[event] onDied : Event<void>
}
```
---
## 5. 能力解锁体系
### 5.1 能力定义
| 能力 ID | 默认状态 | 影响的状态/行为 | 解锁位置 |
|---------|---------|--------------|---------|
| `DoubleJump` | 锁定 | AirState 允许第二次跳跃 | 探索奖励 |
| `WallGrab` | **已解锁** | AirState → WallGrabState 允许 | 初始能力 |
| `AerialDash` | 锁定 | AirState → DashState 允许(消耗充能)| 探索奖励 |
| `Parry` | **已解锁** | ParryState 可进入 | 初始能力 |
| `Swim` | 锁定 | 液体区域不死亡SwimState 可进入 | 主线解锁 |
| `PlungeAttack` | 锁定 | 空中向下冲刺触发下冲 | 探索奖励 |
### 5.2 解锁流程
```
玩家触碰解锁物件AbilityUnlockItem
→ 世界系统发出 OnCollectiblePickedUptype=Ability, abilityId
→ 进程系统处理:将 abilityId 加入已解锁集合
→ 进程系统发出 OnAbilityUnlockedabilityId
→ 玩家系统接收:更新运行时能力标记
→ UI 系统显示能力获得动画
→ 存档系统:在下次存档时持久化
```
---
## 6. 玩家配置参数
以下参数在配置数据中定义,运行时只读:
| 参数 | 类型 | 推荐值 | 说明 |
|------|------|--------|------|
| `maxHP` | Integer | 5 | 初始最大生命值 |
| `maxSoulPower` | Integer | 100 | 灵力上限 |
| `maxSpiritPower` | Integer | 100 | 魄元上限 |
| `spiritRegenRate` | Number | 8.0/s | 魄元每秒自动回复量 |
| `maxSpringCharges` | Integer | 3 | 初始最大灵泉次数 |
| `springKillThreshold` | Integer | 5 | 增加 1 次灵泉所需积分 |
| `iFrameAfterHit` | Duration | 1.2s | 受击后无敌时长 |
| `comboWindowDuration` | Duration | 0.5s | 连击窗口时长 |
| `comboResetDelay` | Duration | 0.3s | 第三击后连击重置延迟 |
| `parryCounterDuration` | Duration | 0.6s | 弹反后反击窗口时长 |
---
## 7. 发出的事件
| 事件 | 触发时机 | 载荷 |
|------|---------|------|
| `OnPlayerDied` | HP 归零 | `void` |
| `OnHPChanged` | HP 任意变化 | `{current, max}` |
| `OnSoulPowerChanged` | 灵力变化 | `{current, max}` |
| `OnSpiritPowerChanged` | 魄元变化 | `{current, max}` |
| `OnSpringChargesChanged` | 灵泉次数变化 | `{current, max}` |
| `OnGeoChanged` | Geo 增减 | `{current, delta}` |
| `OnFormChanged` | 形态切换 | `{newFormId}` |
| `OnParrySuccess` | 弹反成功 | `{counterWindowDuration}` |
| `OnHitConfirmed` | 攻击命中有效目标 | `HitPayload` |
| `OnAbilityUnlocked` | 新能力获得 | `{abilityId}` |