在回合制战斗游戏中,角色可以执行的所有动作都继承自此类。它开始时看起来像这样:
using ActionPtr = std::shared_ptr<Action>;
class Action {
public:
Action(Entity actor, std::uint32_t time) { ... }
virtual ActionPtr execute() = 0;
...
std::uint32_t time; // time that the action will occur. For e.g 10 if it occurs in tick 10 of combat
Entity actor; // the character performing the action
};
进入战斗后,每个人都会获得一个DecideAction,允许角色决定做什么(为玩家提供菜单,或者选择AI选择动作)。 战斗系统保持行动的时间表;按行动发生的时间和行动者打破关系的速度排序。它的更新功能是这样的:
sortTimeline();
ActionPtr followUpAction = timeline.front()->execute();
timeline.removeFront();
timeline.push_back(followUpAction);
例如,执行AiDecideAction会返回后续操作(即该实体选择执行的操作)。攻击动作的执行将返回在依赖于攻击的冷却后发生的决定动作集。这些操作将在下一个时间点添加和处理。
由于操作可以创建其他操作,因此我发现必须将操作可能需要执行的所有可能信息推送到Action类(继承层次结构的根)。这样它就可以正确地构建后续行动。例如
AttackAction::execute() {
...
return ActionPtr(new AiDecide(actor, nextActionTime, allies, enemies);
// allow this entity to decide what to do after attacking
}
攻击行动需要访问盟友和敌人才能将其提供给施工人员;所以我最后修改了Action的构造函数,以获取派生操作可能需要尝试解决此问题的所有可能信息。
有更好的方法吗?我想知道继承是否是模拟这个问题的正确方法。我必须多次修改所有操作,以便构建其他操作所需的信息,这不是理想的。