在游戏开发中,经常会遇到各种各样的技能处理,比如
天火:释放区域内怪物初始扣血,并附加持续性伤害。
冰冻:释放区域内怪物初始扣血,并附加持续性减速。
闪电:释放区域内怪物初始扣血,并附加持续性眩晕。
属性变化:攻击增加50%,防御减少30%,持续N秒。攻击永久增加或减少等等。
本文提供了一种简易的技能设计框架来实现上面的效果,重在其设计思想可以复用。
1.技能效果:
不论是扣血,减速,加攻击,减防御,我们统一看为是技能效果,
public interface ISkillEffect {
public boolean act (float delta,SkillTarget target);
}
public abstract class BaseSkillEffect implements ISkillEffect {
// 作用目标
protected SkillTarget target;
public SkillTarget getTarget() {
return target;
}
public void setTarget(SkillTarget target) {
this.target = target;
}
public void reset() {
this.target = null;
}
}
/**
*
* 基于时间来处理技能效果
* @author haocao
*
*/
public abstract class TemporalSkillEffect extends BaseSkillEffect {
// 持续时间,当前进度时间
private float duration, time;
private boolean began, complete;
public boolean act(float delta, SkillTarget target) {
if (getTarget() == null) {
setTarget(target);
}
if (complete)
return true;
if (!began) {
begin();
began = true;
}
time += delta;
complete = time >= duration;
float percent;
if (complete)
percent = 1;
else {
percent = time / duration;
}
update(percent);
if (complete)
end();
return complete;
}
public abstract void begin();
/** Called the last time {@link #act(float)} is called. */
public abstract void end();
/**
* Called each frame.
*/
abstract protected void update(float percent);
/** Skips to the end of the transition. */
public void finish() {
time = duration;
}
public float getDuration() {
return duration;
}
public void setDuration(float duration) {
this.duration = duration;
}
}
2.技能(技能效果的集合体):
包含技能开始,结束,生效等流程。
一个技能可以拥有不同的技能效果,这样就可以组合出很多种技能。
public interface ISkill {
public void addSkillEffect(ISkillEffect skillEffect);
public void active(float delta);
public void finish();
public void start();
public void init();
}
public abstract class BaseSkill implements ISkill {
private SkillTarget skillTarget;
public ArrayList<ISkillEffect> skillEffects = new ArrayList<ISkillEffect>();
private boolean firstActive = false, finished = false;
@Override
public void addSkillEffect(ISkillEffect skillEffect) {
skillEffects.add(skillEffect);
}
@Override
public void active(float delta) {
if (finished)
return;
if (!firstActive) {
firstActive = true;
start();
}
if (skillEffects.size() == 0) {
finished = true;
finish();
}
ArrayList<ISkillEffect> removeArrayList = new ArrayList<ISkillEffect>();
for (ISkillEffect skillEffect : skillEffects) {
if (skillEffect.act(delta, getSkillTarget())) {
removeArrayList.add(skillEffect);
}
}
skillEffects.removeAll(removeArrayList);
}
public SkillTarget getSkillTarget() {
return skillTarget;
}
public void setSkillTarget(SkillTarget skillTarget) {
this.skillTarget = skillTarget;
}
public ArrayList<ISkillEffect> getSkillEffects() {
return skillEffects;
}
public boolean isFinished() {
return finished;
}
}
3.技能载体:
可以挂着多个技能。
public abstract class SkillTarget {
private ArrayList<BaseSkill> skills = new ArrayList<BaseSkill>();
public float attack,blood,defense,moveSpeed;
public void addSkill(BaseSkill skill){
skill.setSkillTarget(this);
skills.add(skill);
}
// 每帧执行
public void act (float delta) {
ArrayList<BaseSkill> skills = this.skills;
if (skills.size() > 0) {
for (int i = 0; i < skills.size(); i++) {
BaseSkill baseSkill = skills.get(i);
if(!baseSkill.isFinished()){
baseSkill.active(delta);
}else{
skills.remove(i);
i--;
}
}
}
}
public ArrayList<BaseSkill> getSkills() {
return skills;
}
}
使用方法:创建很多技能效果(攻击加成,防御加成,减速等),通过组合技能效果来创建不同的技能。
然后在特定条件下,把技能加到作用对象上。作用对象只要每帧都执行act方法就可以了。