1

ゲーム内のすべてのユニットが共有する関数と変数を保持するクラス「ユニット」があります。私はそれを「兵士」クラスで拡張しました。ユニットには、基本テクスチャを保持する静的変数があります (作成時にそのタイプのすべてのユニットで同じであるため、テクスチャは時間の経過とともに変化する可能性があります)。これらは次によってロードされます。

Unit.baseTexture = content.Load<Texture2D>("worker");
Soldier.baseTexture = content.Load<Texture2D>("soldier");

「Unit」コンストラクターから「Unit」が作成されると、次のようにテクスチャが読み込まれます。

this.texture = Unit.baseTexture;

「兵士」が作成されると、次のようにロードされます。

this.texture = Soldier.baseTexture;

texture は保護された変数であり、静的ではないため、オブジェクトごとに 1 つである必要があります。

メインのゲーム ロジックには、複数の Unit オブジェクトと Soldier オブジェクトが格納された ArrayList があります。

それらをループするとき、私はやっています:

foreach (Unit unit in unitList)
{
    unit.Draw(spriteBatch);
}

Draw は Unit クラスの関数です。

spriteBatch.Draw(this.texture, this.position, Color.White);

ただし、これにより、すべてのユニットが最後に読み込まれたテクスチャ (この場合は兵士のテクスチャ) で描画されます。最初に親クラスを呼び出し、次に子クラスを呼び出したので、これは私を混乱させます。オブジェクトごとのテクスチャが描画されるのに、Soldier テクスチャをロードすると Unit テクスチャも変更されるのはなぜですか?

4

2 に答える 2

1

ここで行うべき正しいことは、BaseTexture のプロパティを使用することだと思います。その後、overrideキーワードを使用して、必要に応じてオーバーライドできます。キーワードを使用newしてメンバーを非表示にすることは避ける必要があります。

例えば:

class Unit
{
   private static Texture2D s_unitTexture = content.Load<Texture2D>("worker");
   protected virtual Texture2D BaseTexture
   {
      get { return s_unitTexture; }
   }

   public Texture2D Texture { get; set; }

   public Unit()
   {
       this.Texture = BaseTexture;
   }

   ...
}

class Soldier : Unit
{
   private static Texture2D s_soldierTexture = content.Load<Texture2D>("soldier");
   protected override Texture2D BaseTexture
   {
      get { return s_soldierTexture; }
   }

   ...
}

このようにして、コンストラクターが実行されると、Unit の各タイプに適した BaseTexture が使用されます。

于 2013-01-06T13:33:27.097 に答える
0

ああ、私はばかです。投稿したらすぐに解決しました。

子クラスの Soldier は独自の baseTexture 変数を定義していませんでした。そのため、Soldier.baseTexture を使用して兵士のテクスチャをロードしていたとき、実際には Unit.baseTexture を使用していました。

基本クラスの代わりにインターフェイスを使用する必要がありますか? すべてのクラスに正しいロード関数と変数があることを確認するには? それ以外の場合は、子オブジェクトを作成して強制的に静的変数をオーバーライドするときに、「new」を使用し続ける必要があります。

于 2013-01-06T13:12:06.650 に答える