3

私はJavaでゲームに取り組んでいますが、どうすればいいのか少し混乱しています。これはトレーディング カード ゲームで、マジックのようなものです。

  • ゲームドライバー
  • カード
  • ウルフカード
  • ラリオンカード

少なくとも 50 種類のカードを持てるようになりたいと思っていますが、それぞれが独自のクラスになっています。私の問題に関しては:

GameDriver クラス内に次のコードがあります。

ArrayList<Cards>  playerHand = new ArrayList<Cards>();
playerHand.add(new WolfCard());
playerHand.add(new TheLarionCard());
System.out.println(((Cards)playerHand.get(1)));

各カードは Cards を拡張し、Cards は GameDriver を拡張します。上記のコードは次のように出力されます。

TheLarionCard[panel0,0,0,0x0,invalid,layout=java.awt.FlowLayout]

しかし今、たとえば TheLarionCard のヘルスを取得したい場合は、次のように最後の行に .health を追加するだけでよいと考えました。

System.out.println(((Cards)playerHand.get(1).health));

しかし、明らかに私はできません。ここで何が間違っていますか?

どんな助けでも素晴らしいです!ありがとうございました!

4

4 に答える 4

3

3つの選択肢があると思います。

  1. それぞれの異なるタイプのカードにプロパティを持たせたいと思いhealthます。この場合、そのプロパティを親クラスに入れることができます。そうすれば、Cardsを拡張するクラスのプロパティを要求することが有効になりますCardsCardsクラスにデータフィールドがある場合、health質問のコードは機能します。

  2. あなたTheLarionCardは健康特性だけを持ちたいのです。その場合、キャストは次のようになります。

    System.out.println(((TheLarionCard)playerHand.get(1).health));
    

    このように、コンパイラは、TheLarionCardクラスではなく、ヘルスプロパティをクラスで検索することを認識していますCards

  3. 実際には、個々のカードクラスがのサブクラスである必要はありませんCards。そのようにした本当に説得力のある理由がない場合は、すべてのカードをCardsクラスの一部にし、それらのさまざまなタイプ(TheLarionCard、WolfCardなど)をデータフィールドで指定することができます。例えば:

    public class Card {
        String type;
    
        public Card(String inType) {
            this.type = inType;
        }
    
        public String toString() {
            return "This is a " + type;
        }
    }
    

    このように、異なるカードの動作を変えたい場合は、それらの値を確認し、typeその値に基づいて異なる動作を割り当てることができます。

    public void awesomeMethod() {
        if ("TheLarionCard".equals(type)) {
            // execute TheLarionCard code
        } else if ("WolfCard".equals(type)) {
            // execute WolfCard code
        }
    }
    

    これは、他の回答のいくつかが話していた抽象ファクトリパターン設計の簡略版です。したがって、インターフェイスを初めて使用する場合は、この方法で構造が機能するかどうかを確認し、後でインターフェイスを追加できます。

于 2012-08-19T01:22:45.033 に答える
1

でインターフェイスまたは抽象メソッドgetHealth()method を定義し、およびCardsで実装する必要があります。次に、次のことができます。WolfCardTheLarionCardplayerHand.get(1).getHealth()

例えば:

public abstract class BaseCard {
  protected int health;

  public abstract int getHealth();
}

public class WolfCard extends BaseCard {
  private int wolfHealthBoost;  

  public int getHealth() {
    return health + wolfHealthBoost;
  }
}

public class TheLarionCard extends BaseCard {
  public int getHealth() {
    return health;
  }
}
于 2012-08-18T23:07:07.980 に答える
0

インターフェースや、そのような複雑な種類のクラスさえも実際には必要ありません。あなたのカードはすべて一般的に同じような振る舞いをしていると思います。それらは特定のタイプであり、特定のアクションを実行でき、アクションや効果をそれらに発生させることができます。したがって、これに必要なカードクラスは1つだけで、これらの一般的な状態を管理するすべてのフィールドとメソッドがあります。行動。

次に、カードクラス(ところで、「カード」に名前を変更することをお勧めします)を継承する個別のクラスを作成できます。たとえば、エフェクトタイプのカード(MTGマナフレアや同等の恐ろしいビサージュなど)がある場合は、次のようになります。クリーチャーカード(MTGのShivanDragonやDragonWhelpなど)では、「duration」や「affectedTypes」などの独自のフィールドを持つEffectCardなどのクラスを作成し、それを使用してManFlareインスタンス、HideousVisageインスタンスなどを作成できます。ヒットポイントやfirstStrikeなどのCreatureCardを使用して、ShivanDragonインスタンスとDragonWhelpインスタンスを作成します。

また、作曲を恐れないでください。カードごとにサブクラス化/追加のクラスを作成する代わりに、上記のような単純な階層を作成し、より具体的な詳細を指示する「コマンド」または「アクション」クラスを渡します。EffectCardクラスのFirstStrikeインスタンスは、CreatureCardインスタンスに影響を与える方法を具体的に指示する「アクション」インスタンスで初期化できるように、CreatureCardクラスのShivanDragonインスタンスには、Redを利用して攻撃を増やす方法を指示するアクションがあります。土地カード等

于 2012-08-18T23:46:19.207 に答える
0

これらのクラスにヘルス属性のゲッターがあるかどうかを確認する必要があります。プライベート属性はクラスの外部からアクセスできません。

health 属性を返す新しいメソッド getHealth() を作成し、最後の行のドットの後に追加します。

ところで、そのステレオタイプで ArrayList を既に定義している場合は、Cards クラスをキャストする必要はありません。

于 2012-08-18T23:09:34.290 に答える