This is just a collision event system I made for my game, all you have to do it invoke the method 'AddCollisionHook' and give it the entities you want it to monitor for collisions and your delegate method to answer the event.
Its 'fairly' quick and will only fire off the method that is watching the entities that collide and supports a single delegate watching multiple collisions. I have not tested the 'RemoveCollisionHook(OnCollision Delegate, Entity A, Entity B)' method yet, but it should work fine or only require a small tweak to fix, just post here if you have a problem.
This code will probably need an update with v0.5.0 and will no longer be required for v0.6.0.
The delegate, put it outside a class, near the using statements is usually where you put it.
Code: Select all
public delegate void OnCollision(Controller ContactInfomration, EventArgs e);
Code: Select all
private static Hashtable Entities = new Hashtable();
private static Hashtable DelegateParams = new Hashtable();
public static void AddCollisionHook(Entity A, Entity B, OnCollision Delegate)
{
if (!(DelegateParams.ContainsKey(Delegate)))
{
List<DoubleEnt> EntList = new List<DoubleEnt>();
EntList.Add(new DoubleEnt(A, B));
DelegateParams.Add(Delegate, EntList);
}
else
{
((List<DoubleEnt>)DelegateParams[Delegate]).Add(new DoubleEnt(A, B));
}
if (Entities.ContainsKey(A))
{
((List<Entity>)Entities[A]).Add(B);
}
else if (Entities.ContainsKey(B))
{
((List<Entity>)Entities[B]).Add(A);
}
else
{
List<Entity> HashList = new List<Entity>();
HashList.Add(B);
Entities.Add(A, HashList);
}
}
public static void RemoveCollisionHook(OnCollision Delegate)
{
foreach (DoubleEnt DEnt in ((List<DoubleEnt>)DelegateParams[Delegate]))
{
Entity A = DEnt.a;
Entity B = DEnt.b;
if (Entities.ContainsKey(A) && !(Entities.ContainsKey(B)))
{ //Entities contains A but not B
((List<Entity>)Entities[A]).Remove(B);
if (((List<Entity>)Entities[A]).Count == 0)
{
Entities.Remove(A);
}
}
else if (Entities.ContainsKey(B) && !(Entities.ContainsKey(A)))
{ //Entities contains B but not A
((List<Entity>)Entities[B]).Remove(A);
if (((List<Entity>)Entities[B]).Count == 0)
{
Entities.Remove(B);
}
}
else
{ //Entities contains A and B
if (((List<Entity>)Entities[A]).Contains(B))
{//Entities[A] Contains B
((List<Entity>)Entities[A]).Remove(B);
if (((List<Entity>)Entities[A]).Count == 0)
{
Entities.Remove(A);
}
}
else
{//Entities[B] Contains A
((List<Entity>)Entities[B]).Remove(A);
if (((List<Entity>)Entities[B]).Count == 0)
{
Entities.Remove(B);
}
}
}
}
DelegateParams.Remove(Delegate);
}
public static void RemoveCollisionHook(OnCollision Delegate, Entity A, Entity B)
{//Removes a single entity pair from the Delegate
foreach (DoubleEnt DEnt in ((List<DoubleEnt>)DelegateParams[Delegate]))
{
if ((DEnt.a == A && DEnt.b == B) || (DEnt.a == B && DEnt.b == A))
{
((List<DoubleEnt>)DelegateParams[Delegate]).Remove(DEnt);
}
}
if (Entities.ContainsKey(A) && !(Entities.ContainsKey(B)))
{ //Entities contains A but not B
((List<Entity>)Entities[A]).Remove(B);
if (((List<Entity>)Entities[A]).Count == 0)
{
Entities.Remove(A);
}
}
else if (Entities.ContainsKey(B) && !(Entities.ContainsKey(A)))
{ //Entities contains B but not A
((List<Entity>)Entities[B]).Remove(A);
if (((List<Entity>)Entities[B]).Count == 0)
{
Entities.Remove(B);
}
}
else
{ //Entities contains A and B
if (((List<Entity>)Entities[A]).Contains(B))
{//Entities[A] Contains B
((List<Entity>)Entities[A]).Remove(B);
if (((List<Entity>)Entities[A]).Count == 0)
{
Entities.Remove(A);
}
}
else
{//Entities[B] Contains A
((List<Entity>)Entities[B]).Remove(A);
if (((List<Entity>)Entities[B]).Count == 0)
{
Entities.Remove(B);
}
}
}
}
public static bool IsHooked(OnCollision Delegate)
{
return DelegateParams.ContainsKey(Delegate);
}
private static void OnCollision(Controller ContactInformation, EventArgs e)
{
List<OnCollision> DelegatesToInvoke = new List<OnCollision>();
foreach (OnCollision Delegate in DelegateParams.Keys)
{
foreach (DoubleEnt DEnt in ((List<DoubleEnt>)DelegateParams[Delegate]))
{
Entity A = DEnt.a;
Entity B = DEnt.b;
if ((A == ContactInformation.colliderA ||
A == ContactInformation.colliderB) &&
(B == ContactInformation.colliderA ||
B == ContactInformation.colliderB))
{
DelegatesToInvoke.Add(Delegate);
}
}
}
foreach (OnCollision Delegate in DelegatesToInvoke)
{
Delegate.Invoke(ContactInformation, e);
}
}
Code: Select all
List<Controller> CollisionsToReport = new List<Controller>();
foreach (Entity ent in Entities.Keys)
{
if (ent is CompoundBody)
{
List<Controller> controllers = new List<Controller>();
getControllers(ref controllers, ent);
if (controllers.Count > 0)
{
foreach (Entity entB in ((List<Entity>)Entities[ent]))
{
foreach (Controller controller in controllers)
{
if (controller.contacts.Count > 0)
{
if (controller.colliderA == entB || controller.colliderB == entB)
{
if (controller.colliderA == entB)
controller.colliderB = ent;
else
controller.colliderA = ent;
CollisionsToReport.Add(controller);
}
}
}
}
}
}
else if (ent.controllers.Count > 0)
{
foreach (Entity entB in ((List<Entity>)Entities[ent]))
{
foreach (Controller controller in ent.controllers)
{
if (controller.contacts.Count > 0)
{
if (entB is CompoundBody)
{
List<Entity> ents = new List<Entity>();
getSubbodies(ref ents, entB);
foreach (Entity entC in ents)
{
if (controller.colliderA == entC || controller.colliderB == entC)
{
if (controller.colliderA == entC)
controller.colliderA = entB;
else
controller.colliderB = entB;
CollisionsToReport.Add(controller);
}
}
}
else
{
if (controller.colliderA == entB || controller.colliderB == entB)
{
CollisionsToReport.Add(controller);
}
}
}
}
}
}
}
foreach (Controller control in CollisionsToReport)
{
OnCollision(control, EventArgs.Empty);
}
Code: Select all
using BEPUphysics;
namespace YOUR PROJECT NAME HERE
{
public class DoubleEnt
{
public DoubleEnt(Entity A, Entity B)
{
a = A;
b = B;
}
public Entity a;
public Entity b;
}
}