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# 事件。查看wikipedia中的碰撞示例。

于 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 回答