3

我正在为android手机开发一个基于java的回合制RPG,我目前正在尝试弄清楚如何处理具有超出损害之外的额外变量的攻击。例如,我想让火焰攻击在目标具有燃烧效果时造成额外 10% 的伤害。我有点不确定如何以一种有效的方式进行此操作,并且允许将来添加到我的状态/攻击系统中。

所以这是我对如何做到这一点的想法:

  1. 一系列 if/else 语句或 switch

    switch (status) {
    case burned:
        if (type == fire) {
            damage = damage * 1.1;
        }
        break;
    case frozen:
        if (type == ice) {
            damage = damage * 2;
        }
        break;
    }
    

    如果每种状态都有很多可能的结果,我也可以使用嵌套开关。

  2. 使用二维数组,其x值为状态,y值为攻击或类型。当您检查[x][y]它时,它会返回一个数值,表示攻击中将发生的变化。

          Burned   Frozen
    
    Fire  [1.1]    [1]
    
    Ice   [1]      [2]
    

虽然这两个现在看起来都很好,但我不确定它是否适用于未来。现在,我当然可以使用改变伤害量的组合,但是对于具有非数值效果的攻击,我不能简单地返回一个值并将我的伤害乘以该值呢?

是否有可能生成某种代表以下情况的代码:

烧毁 = 1 在第一位置,冻结 = 2
火力攻击 = f 在第二位置,冰 = i
伤害模组在第三位

所以对着火的敌人进行火力攻击1-f-1.1

4

3 回答 3

7

您应该尝试使用多态性。

对于开关/if-else

创建一个表示攻击的接口,并让它声明一个方法:

public interface Attack {
    double doAttack(double baseDamage);
}

然后创建实现此接口的类:

public class FireAttack implements Attack {
    double doAttack(double baseDamage){
        return 1.1 * baseDamage;
    }
}

public class IceAttack implements Attack {
    double doAttack(double baseDamage){
        return 2 * baseDamage;
    }
}

然后,不要在代码中使用 switch 语句,而是执行以下操作:

public class Player {
    private Attack mAttack;

    // Somewhere in your code, you setup something like
    void setFireWeapon(){
        mAttack = new FireAttack();
    }

    // This is where the attack is taken care of
    double inflictDamage() {
        return mAttack.doAttack();
    }
}

这使您可以做的是实现您将来可能希望的任何新类型的攻击,并简单地分配Attack mAttack这个新的接口实现AttackbaseDamage * aDouble这是一个简单的例子,你可以做一些比你想要的更强大的东西。

对于状态(烧毁/冻结)

有很多方法可以实现冻结等状态。首先,您可以使用我上面解释的相同模式。

除了拥有成员之外,您还可以使用您喜欢Attack mAttack的名称或任何名称添加类似的逻辑。HealthStatus mHealthStatus然后调用inflictDamage()会将对象重定向mAttackmHealthStatus对象。

然后这个HealthStatus类将再次成为一个接口,

public interface HealthStatus {
    double considerAttack(Attack anAttack);
}

它将具有各种状态的实现:

public class NormalStatus implements HealthStatus{
    double considerAttack(Attack anAttack){
        return anAttack.doAttack(); // No change here
    }
}

public class FrozenStatus implements HealthStatus{
    double considerAttack(Attack anAttack){
        return 0; // Can't attack when froxen
    }
}

public class BurnedStatus implements HealthStatus{
    double considerAttack(Attack anAttack){
        return anAttack.doAttack() * 2.0; // Get berserk when on fire!
    }
}

您也可以使用其他模式。我建议您查看设计模式,它可以解决您所面临的问题。

仅举几个。

于 2012-08-03T17:06:21.603 回答
0

AntonieG 走在正确的轨道上。这个问题的一般解决方案是使用策略设计模式。

战略

动机

常见的情况是类仅在行为上有所不同。对于这种情况,将算法隔离在单独的类中是一个好主意,以便能够在运行时选择不同的算法。

意图

定义一系列算法,封装每个算法,并使它们可互换。策略让算法独立于使用它的客户而变化。

执行

策略模式实施 http://www.oodesign.com/strategy-pattern.html

另请查看以下链接。

http://en.wikipedia.org/wiki/Strategy_pattern

http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/22/applying-strategy-pattern-instead-of-using-switch-statements.aspx

于 2012-08-03T17:19:19.833 回答
0

你的想法似乎太线性了。使用面向对象的原则来设计你的游戏。为扩展通用攻击的攻击创建类。

public abstract class Attack{
    protected String attackName;
    protected Double damage;

    public Attack(){
        attackName = "Standard";
        damage = 1.0;
    }

    public Double getDamage(){
        return damage;
    }

    public String getAttackName(){
        return attackName;
    }
}

然后扩展:

public class FireStorm extends Attack{
    public FireStorm(String attackName, Double damage){
        this.attackName = attackName;
        this.damage = damage;
    }

    @Override
    public Double getDamage(Enemy target){
        if(target.hasBurnEffect()){
            damage *= 2.0;
        } else {
            damage = super.getDamage();
        }

        return damage;
    }
}

我真的不太了解你游戏中的事物范围,所以我无法对其进行过多描述。但是,如果您想让您的游戏按照您的建议灵活和可扩展,那么您将需要使用继承和其他面向对象编程的原则。

于 2012-08-03T17:23:23.063 回答