2013-05-05 136 views
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被調用。

是這樣的可能嗎?

+0

它很難理解你正在嘗試做什麼。你是說當碰撞發生時,你會稱之爲'SomethingThatCollides'方法?請提供更多解釋 – prashantsunkari 2013-05-05 01:02:18

+0

@Andrew:如果我有objA,objB和objC,它們都可以與它們全部相撞? AB,AC和BC會有碰撞方法嗎? – 2013-05-05 01:28:59

+0

或者它是一個主人與其他人相互碰撞的對象,沒有對他人之間的相互碰撞進行處理? – 2013-05-05 01:29:36

回答

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查看碰撞示例。

+0

關鍵是創建一個單獨的方法來處理每個碰撞,而不必進行不必要的裝箱和類型檢查。是否真的沒有辦法這樣做? – 2013-05-05 01:21:29

+0

在維基百科上查看[double-dispatch](http://en.wikipedia.org/wiki/Double_dispatching)。 – 2013-05-05 01:32:48

0

這是uggly,但是......你可以按類型事件的dicionary:

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); 
} 
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發佈。

+0

現在這是... – 2013-05-05 03:11:16

+0

嗯,聽起來很有趣,但我不能從EventsHolder外部調用'EventsHolder .CollideEvent',我該如何解決這個問題? – 2013-05-05 04:15:12

+0

在EventsHolder中創建一個'CallEvent'靜態方法來調用事件。現在在'RaiseCollision'中調用該方法。 (我編輯了答案,但必須等待某人的修改) – 2013-05-05 04:40:07