1

今回は仮想フィールドに問題があります。

ゲームオブジェクトのコアクラスがあります。このクラスには、Model クラス オブジェクトを含むフィールドが含まれています。モデルのオブジェクトには、位置などの値が含まれています。

今-描画中に、モデルから各オブジェクトの位置を読み取る必要があります。問題は、デフォルトのモデルクラスの代わりに派生を使用しているときに始まります。例:

abstract class GenericGameObject { public DefaultGameObjectModel Model = new DefaultGameObjectModel(); }
class Missile : GenericGameObject { public new MissileModel Model = new MissileModel(); }

class DefaultGameObjectModel { public Vector2 Position = new Vector2(){X=0}; }
class MissileModel : DefaultGameObjectModel { }

Missile m = new Missile();
m.Model.Position.X = 10;
// NOT OK! ((GenericGameObject)m).Model.Position.X == 0

モデルをフィールドではなく仮想プロパティとして定義しようとしましたが、派生プロパティはそのベースと同じ型でなければならないため、これは失敗します。他の多くのモデル タイプがあるため、キャスティングは無駄です。ベースからではなく、派生クラスから値を読み取りたい場合はどうすればよいですか?

私はすでにこの質問をしましたが、答えは解決策をもたらしませんでした。説明:

  • インターフェイス IGameObjectModel を使用する

    コンセプトは良いのですが、フィールドを強制する必要があります。インターフェイスはフィールドを定義できないため、プロパティを定義する必要があります。しかし、Position はフィールドではないため、IGameObjectModel.Position.X=10 を実行できません。

  • GenericGameObject を GenericGameObject や Missile などのジェネリック タイプにするために、GenericGameObject から派生したタイプにするため に、ミサイルを GenericGameObject にキャストして、通常はそれらのオブジェクトを同じリストに格納することができませんでした。もちろん、これら 2 つが継承できる主な基本型を作成することはできますが、Model フィールドにアクセスすることはできません。

  • モデルをフィールドではなくプロパティにします。 派生クラスのプロパティ タイプを変更することはできません。

どうすればいいですか?

4

5 に答える 5

2

「仮想フィールド」などというものはありません。プロパティメソッドのみを仮想にすることができます。

Missle クラスでは、モデルという名前の継承されたメンバーを非表示に する修飾子として new キーワードを使用しているようです。

この方法で継承されたメンバーを非表示にすると、ポリモーフィックな動作が得られません。基本クラスのコード (Model フィールドを参照している場合) が期待どおりに機能しない可能性があるため、これは問題です。

最善の策: プロパティを使用します。必要に応じて、キャストまたは一般化 (メンバーを基本クラスに移動) します。

于 2009-04-07T18:01:38.523 に答える
1

「IGameObjectModel.Position.X=10」を実行できないプロパティを持つインターフェイスを使用した場合、あなたは言いました。これは、Vector2が構造体であり、したがって値型のセマンティクスを持っているためだと思います。これが正しければ、Positionプロパティを元の値から計算された新しいVector2に割り当てるだけです。例えば:

Missile m = new Missile();
m.Model.Position = new Vector2()
{
    X = m.Model.Position.X + 10,
    Y = m.Model.Position.Y
};
于 2009-04-07T17:42:21.097 に答える
0

ジェネリックを使ってみましたか?ジェネリックを使用すると、ゲーム オブジェクト モデルをゲーム オブジェクトから分離できます。その後、任意のゲーム オブジェクト モデルでゲーム オブジェクトをインスタンス化できます。ゲーム オブジェクトは、標準インターフェイスを介してゲーム オブジェクト モデルと通信できます。

interface IGameObjectModel {
    void Shoot();
        :
}

class GameObject<TModel> where TModel:IGameObjectModel {
    public TModel Model;
    public GameObject(TModel model) {
        Model = model;
    }
    public void Shoot() {
        Model.Shoot();
    }
        :
}

class MissleModel : IGameObjectModel {
    public void Shoot() {
        :
    }   
}

上記で、ミサイルモデルでゲームオブジェクトをインスタンス化できます:-

MissleModel model = new MissleModel();
GameObject<MissleModel> obj =
    new GameObject<MissleModel>(model);
于 2009-06-28T17:42:03.800 に答える