3

私はAndroid携帯用のJavaでターンベースのRPGを開発しており、現在、ダメージ以外の追加の変数を持つ攻撃を処理する方法を見つけようとしています。たとえば、ターゲットに火傷効果がある場合、火の攻撃でさらに10%のダメージを与えたいと思います。これを効率的に行う方法と、ステータス/攻撃システムに将来追加できる方法が少しわかりません。

だからここに私がこれを行う方法についての私の考えがあります:

  1. 一連のif/elseステートメントまたはスイッチ

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

    ステータスごとに可能な結果が多数ある場合は、ネストされたスイッチを使用することもできます。

  2. x値がステータスで、y値が攻撃またはタイプである2次元配列を使用します。チェックする[x][y]と、攻撃時に発生する変化の数値が返されます。

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

これらは両方とも今のところ問題ないように見えますが、将来的に機能するかどうかはわかりません。今のところ、確かにダメージ量を変える組み合わせを使うことはできますが、単純に値を返してダメージにその値を掛けることができない、数値以外の効果を持つ攻撃はどうでしょうか?

次のような状況を表すある種のコードを生成することは可能でしょうか。

燃焼=1、最初の位置、凍結= 2
火の攻撃=2番目の位置のf、氷= i
ダメージmodは3番目の位置にあります

したがって、燃やされた敵への火の攻撃はになります1-f-1.1

4

3 に答える 3

7

ポリモーフィズムを使用するようにしてください。

スイッチ/if-elsesの場合

攻撃を表すインターフェースを作成し、単一のメソッドを宣言させます。

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実装し、この新しいインターフェイスの実装を割り当てるだけで済みますAttack。これは些細な例です。必要な場合よりもはるかに強力な処理を実行できますbaseDamage * 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 に答える