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