1

私はゲームを作成しており、オブジェクトが互いに衝突を処理する方法を作成しようとしています。私は次のようなことをしたい:

//Imaginary C#

public SomethingThatCollides()
{
    CollisionEvent<ObjectA> += CollisionWithObjA;
    CollisionEvent<ObjectB> += CollisionWithObjB;
}

void CollisionWithObjA(ObjectA other)
{
    //Do something
}
void CollisionWithObjB(ObjectB other)
{
    //Do something else
}

たとえば、CollisionEvent<ObjectA>(おそらく何らかの衝突チェック コードによって) が発生した場合、CollisionWithObjA呼び出される必要があります。についても同じですCollisionWithObjB。ObjectB との衝突が検出されると、呼び出されるCollisionEvent<ObjectB>イベントが発生しCollisionWithObjBます。

このようなことは可能ですか?

4

3 に答える 3

1

クラスがジェネリックであり、静的フィールドがある場合、キーが型である辞書のように機能します

public class Something {
    public class EventsHolder<T> 
    {
       static event Action<T> CollideEvent;
    }

    public void AddEvent<T>(Action<T> collisionEvent) 
    {
      EventsHolder<T>.CollideEvent = collisionEvent;
    }

    public void RaiseCollision<T>(T Obj)
    {
      var Event = EventsHolder<T>.CollideEvent;
      if (Event != null) Event(Obj);
    }
}

欠点は、不適切な静的フィールドを使用することです。この場合、@Daniel が投稿したコードを使用できます。

于 2013-05-05T02:43:05.867 に答える
0

そのような一般的なイベントを実際に作成することはできません。衝突したオブジェクトもカプセル化する特別なイベント引数クラスを作成し、イベント ハンドラー メソッドでその型をチェックすることをお勧めします。

public class CollisionEventArgs : EventArgs {
  public object Object {
    get; private set;
  }
  // ...
}

これを使用するには、特別なディスパッチャ メソッドが必要です。

class SomethingThatCollides {

  public SomethingThatCollides(CollisionManager cm) {
    cm.CollisionEvent += CollisionWithObj;
  }

  void CollisionWithObj(object sender, CollisionEventArgs args) {
    if (args.Object is ObjectA) {
      CollisionWithObjA((ObjectA)args.Object);
    }
    else if (args.Object is ObjectB) {
      CollisionWithObjB((ObjectB)args.Object);
    }
  }

  // ...
}

または、C# イベントを使用せずに、二重ディスパッチでこれを解決しようとすることもできます。衝突の例については、ウィキペディアを参照してください。

于 2013-05-05T01:15:00.120 に答える
0

それは醜いですが...タイプごとのイベントの辞書を持つことができます:

Dictionary<Type, object> MyEventsByType;

event Action<A> CollisionEventA;
event Action<B> CollisionEventB;
event Action<C> COllisionEventC;

void Initialize()
{
    MyEventsByType = new Dictionary<Type, object>();

    MyEventsByType.Add(typeof(A), CollisionEventA);
    MyEventsByType.Add(typeof(B), CollisionEventB);
    MyEventsByType.Add(typeof(C), CollisionEventC);
}

void RaiseCollision<T>(T Obj)
{
    Action<T> Event = (Action<T>)MyEventsByType[typeof(T)];
    if (Event != null) Event(Obj);
}
于 2013-05-05T02:27:42.567 に答える