对于问题1,可以将技能配表的数据结构进行调整,引入事件数据结构,将技能效果与事件一一对应。例如,定义技能效果的数据结构如下:
class SkillEffect {
int target; // 攻击目标类型
int effect; // 效果类型
int turns; // 持续回合数
float amount; // 数值
int event; // 事件类型
}
其中,event是事件类型,可以为0表示无事件,其他数字表示特定的事件类型。定义事件数据结构如下:
class SkillEvent {
int effectIndex; // 触发事件对应的技能效果索引
int event; // 事件类型
}
在技能配表数据中,可以将技能效果和事件数据分别存储在不同的数据结构中,例如:
class SkillData {
int id; // 技能ID
List<SkillEffect> effects; // 技能效果
List<SkillEvent> events; // 事件格数据
}
这样可以让程序知道一个完整的技能里的多种技能效果,包含哪些事件技,并且每种事件技分别对应哪些效果。
对于问题2,可以在释放技能的逻辑中,遍历每个技能效果,判断是否有事件技。如果有事件技,则将事件注册到相应的事件处理器中,事件处理器负责监控触发相应的事件,并执行对应的效果。可以使用观察者模式实现事件处理器。在技能释放脚本中,将所有技能效果注册到对应的事件处理器中,事件处理器负责监听比如"敌人流血增伤"、"阵亡增益"等事件,一旦事件触发,处理器便会通知对应的技能效果进行操作。
例如,对于技能1中的第3和第4、5、6个效果,可以分别定义事件为"敌人流血"和"友军阵亡",将其注册到事件处理器中,事件处理器监听相应的事件并通知对应效果生效。
class SkillEventProcessor {
map<int, list<int>> effectEventMap; // 技能效果与事件的映射表
map<int, SkillEventCallback> eventCallbackMap; // 每个事件类型对应的回调处理函数
void registerEffectWithEvent(int effectIndex, int event) {
if (effectEventMap.find(event) == effectEventMap.end()) {
effectEventMap[event] = list<int>();
}
effectEventMap[event].push_back(effectIndex);
}
void registerCallbackForEvent(int event, SkillEventCallback callback) {
eventCallbackMap[event] = callback;
}
void processEvent(int event, SkillEventData eventData) {
if (eventCallbackMap.find(event) != eventCallbackMap.end()) {
for (auto effectIndex : effectEventMap[event]) {
auto& effect = effects[effectIndex];
if (effect.event == event) {
eventCallbackMap[event](effect, eventData);
}
}
}
}
}
在技能释放脚本中,注册事件处理器,以及每个事件所对应的回调函数:
class MySkillScript {
SkillEventProcessor eventProcessor; // 注册事件处理器
// 注册事件和回调函数
void registerEventsAndCallbacks(SkillData skill) {
for (auto event : skill.events) {
eventProcessor.registerEffectWithEvent(event.effectIndex, event.event);
switch (event.event) {
case EVENT_ENEMY_BLEED:
eventProcessor.registerCallbackForEvent(EVENT_ENEMY_BLEED, [=](SkillEffect& effect, SkillEventData& data) {
if (data.target.isBleeding()) {
applyEffect(effect, data); // 对目标施加效果
}
});
break;
case EVENT_ALLY_DIED:
eventProcessor.registerCallbackForEvent(EVENT_ALLY_DIED, [=](SkillEffect& effect, SkillEventData& data) {
if (data.allyDied()) {
applyEffect(effect, data); // 对自身施加效果
}
});
break;
// 处理其他事件...
}
}
}
void castSkill(SkillData skill, list<Target> targets) {
registerEventsAndCallbacks(skill);
// 遍历技能效果
for (auto effect : skill.effects) {
if (effect.event == 0) {
applyEffect(effect, targets); // 直接对目标施加效果
}
}
}
void applyEffect(SkillEffect effect, list<Target> targets) {
// 根据效果的目标类型,从传入的目标列表中选择目标
auto targets = chooseTargets(effect.target, targets);
// 根据效果类型和数值,对目标施加效果
for (auto target : targets) {
switch (effect.effect) {
case EFFECT_INCREASE_ATTACK:
target.increaseAttack(effect.amount, effect.turns);
break;
case EFFECT_INCREASE_DEFENSE:
target.increaseDefense(effect.amount, effect.turns);
break;
case EFFECT_EXTRA_DAMAGE_TO_BLEEDING:
// 对流血目标施加额外伤害效果
auto eventData = SkillEventData(target);
eventProcessor.processEvent(EVENT_ENEMY_BLEED, eventData);
break;
// 处理其他效果...
}
}
}
}
通过这种设计思路,可以实现单个技能的多种效果里糅合着不同的事件技且还对应不同的效果。