Files
bl/docs/fight-input-controller-binding.md
xinian f473c54880
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat: 支持多站位战斗控制绑定模式
2026-04-05 00:03:32 +08:00

195 lines
5.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Fight Input 控制绑定说明
日期2026-04-04
## 1. 背景
当前战斗模型中一个 `Input` 对应一个战斗站位`actorIndex`
每个 `Input` 通过 `Input.Player` 绑定操作者
当前建战主路径已收敛为`WithFightInputs(ourInputs, oppInputs)`
先由调用方创建并组装双方 `Input`再传给战斗模块
为了同时支持以下两种玩法新增了可配置绑定策略
1. 双打一个玩家控制多个站位单人多 `Input`
2. 组队一个玩家控制一个站位每人一个 `Input`
## 2. 绑定策略
文件`logic/service/fight/new_options.go`
- `InputControllerBindingKeep`
- 含义保持输入中已有 `Input.Player` 绑定不覆盖
- 适用调用方已手动构造 `Input` 绑定
- `InputControllerBindingSingle`
- 含义单侧全部站位统一绑定为 `players[0]`
- 适用双打中一个人控制多个站位
- `InputControllerBindingPerSlot`
- 含义按站位顺序绑定为 `players[i]`
- 适用组队中一人一个站位
- 说明 `players` 数量不足时回退绑定 `players[0]`
## 3. 选项接口
文件`logic/service/fight/new_options.go`
新增选项
```go
WithInputControllerBinding(mode int)
```
## 4. 生效时机
文件`logic/service/fight/new.go`
`buildFight` 构建完 `Our/Opp` 输入后先执行控制绑定再执行上下文绑定
1. `bindInputControllers(f.Our, f.OurPlayers, opts.controllerBinding)`
2. `bindInputControllers(f.Opp, f.OppPlayers, opts.controllerBinding)`
3. `bindInputFightContext(...)`
4. `linkTeamViews()`
5. `linkOppInputs()`
## 5. 使用示例
### 5.1 双打单人控多站位
```go
fight.NewFightWithOptions(
fight.WithFightPlayersOnSide(
[]common.PlayerI{ourPlayer},
[]common.PlayerI{oppPlayer},
),
fight.WithFightInputs(ourInputs, oppInputs),
fight.WithInputControllerBinding(fight.InputControllerBindingSingle),
)
```
### 5.2 组队一人一个站位
```go
fight.NewFightWithOptions(
fight.WithFightPlayersOnSide(
[]common.PlayerI{ourP1, ourP2},
[]common.PlayerI{oppP1, oppP2},
),
fight.WithFightInputs(ourInputs, oppInputs),
fight.WithInputControllerBinding(fight.InputControllerBindingPerSlot),
)
```
### 5.3 仅传已绑定 Input推荐灵活接入
```go
ourInputs := []*input.Input{
input.NewInput(nil, ourP1), // 站位0
input.NewInput(nil, ourP2), // 站位1
}
oppInputs := []*input.Input{
input.NewInput(nil, oppP1), // 站位0
input.NewInput(nil, oppP2), // 站位1
}
fc, err := fight.NewFightWithOptions(
fight.WithFightInputs(ourInputs, oppInputs),
// 不传 WithFightPlayersOnSide 也可
// owner/opponent 与 side players 会从 inputs 自动提取
)
_ = fc
_ = err
```
说明`InputControllerBindingSingle/PerSlot` 会覆盖 `ourInputs/oppInputs` 中原有的 `Input.Player` 绑定`Keep` 不覆盖
## 6. 新模式绑定实例逐模式
以下示例假设我方有两个站位`ourInputs[0]``ourInputs[1]`
### 6.1 Keep保持输入原绑定
调用
```go
fight.NewFightWithOptions(
fight.WithFightInputs(ourInputs, oppInputs),
fight.WithInputControllerBinding(fight.InputControllerBindingKeep),
)
```
输入调用前
- `ourInputs[0].Player = ourP1`
- `ourInputs[1].Player = ourP2`
结果调用后
- `ourInputs[0].Player = ourP1`
- `ourInputs[1].Player = ourP2`
适用调用方已提前把每个站位绑定好不希望框架覆盖
### 6.2 Single单人控制全部站位
调用
```go
fight.NewFightWithOptions(
fight.WithFightPlayersOnSide(
[]common.PlayerI{ourCaptain},
[]common.PlayerI{oppCaptain},
),
fight.WithFightInputs(ourInputs, oppInputs),
fight.WithInputControllerBinding(fight.InputControllerBindingSingle),
)
```
输入调用前
- `ourInputs[0].Player = ourP1`
- `ourInputs[1].Player = ourP2`
结果调用后
- `ourInputs[0].Player = ourCaptain`
- `ourInputs[1].Player = ourCaptain`
适用双打或多站位由同一玩家操作
### 6.3 PerSlot按站位顺序绑定玩家
调用
```go
fight.NewFightWithOptions(
fight.WithFightPlayersOnSide(
[]common.PlayerI{ourP1, ourP2},
[]common.PlayerI{oppP1, oppP2},
),
fight.WithFightInputs(ourInputs, oppInputs),
fight.WithInputControllerBinding(fight.InputControllerBindingPerSlot),
)
```
输入调用前
- `ourInputs[0].Player = anyA`
- `ourInputs[1].Player = anyB`
结果调用后
- `ourInputs[0].Player = ourP1`
- `ourInputs[1].Player = ourP2`
补位规则 `players` 数量不足例如只传一个 `ourP1`剩余站位回退绑定 `players[0]`
## 7. 注意事项
1. 默认模式是 `InputControllerBindingKeep`不影响现有调用
2. 若传入 `WithFightInputs(...)` 且每个 `Input.Player` 已预先绑定可继续用默认模式
3. 仅传 `WithFightInputs(...)` 也可工作框架会从 `ourInputs/oppInputs` 自动提取 `ourPlayers/oppPlayers`并以各侧首位玩家作为 owner/opponent
4. 推荐在新组队逻辑中显式传 `WithInputControllerBinding(...)`避免调用方歧义