/// <summary> /// Run collision checking on all entities /// </summary> private void CollideEntities() { quadTree.CheckedList.Clear(); List <NumberPopup> popups = new List <NumberPopup>(); foreach (ICollides self in entityHandler.EntityList.OfType <ICollides>()) { ICollides other = quadTree.CollidingWith(self); if (other != null) { bool selfCollided = self.TryReactToCollision(other.Damage, other.Vel, other.Mass, other.Team, other is Ammo); bool otherCollided = other.TryReactToCollision(self.Damage, self.Vel, self.Mass, self.Team, self is Ammo); if (selfCollided && other.Damage > 0) { popups.Add(numberPopupFac.Create(self.RealPos, other.Damage)); } if (otherCollided && self.Damage > 0) { popups.Add(numberPopupFac.Create(other.RealPos, self.Damage)); } } } foreach (NumberPopup p in popups) { entityHandler.Track(p); } }
/// <summary> /// Traverse the tree to fetch the node that contains the specified collideable object /// </summary> /// <param name="obj">collideable object</param> /// <returns>The containing node</returns> private Node FetchContaining(ICollides obj) { //guard if (obj == null) { return(null); } //end condition (no more child nodes) if (childNodes == null) { if (ICollidesList.Contains(obj)) { return(this); } else { return(null); } } else { //traverse foreach (Node n in childNodes) { if (n.ContainsPos(obj.RealPos)) { return(n.FetchContaining(obj)); } } return(null); } }
/// <summary> /// Register collidable to the right node /// </summary> public void Register(ICollides obj) { //guards if (obj == null) { return; } if (!SwinGame.RectOnScreen(grid)) { return; } //end condition if (childNodes == null) { ICollidesList.Add(obj); return; } //find the node which contains the entiites position foreach (Node n in childNodes) { //only explore traverse relevant nodes if (n.ContainsPos(obj.RealPos)) { n.Register(obj); } } }
/// <summary> /// remove the collideable entity from the tree /// </summary> /// <param name="obj">collideable object</param> public void Deregister(ICollides obj) { Node n = FetchContaining(obj); if (n != null) { n.ICollidesList.Remove(obj); } }
public bool OnCollisionFunction(Geom geom1, Geom geom2, ContactList contactList) { GeomDC g1 = geom1 as GeomDC; GeomDC g2 = geom2 as GeomDC; if (g1 == null || g2 == null) { return(true); } ICollides col1 = g1.thisObject as ICollides; if (col1 == null) { return(true); } return(col1.OnCollision(g2.thisObject)); }
/// <summary> /// check if the passed in collideable is colliding with anything /// </summary> /// <returns>return what it is colliding w ith</returns> public ICollides CollidingWith(ICollides self) { Node n = FetchContaining(self); //guard if (n == null) { return(null); } Node[] adjacentNodes = n.parent.childNodes; foreach (Node adjacentNode in adjacentNodes) { foreach (ICollides other in adjacentNode.ICollidesList) { if (self != other && self.Team != other.Team && !adjacentNode.CheckedList.Contains(other)) { if (IsColliding(self.BoundingBox, other.BoundingBox)) { if (self is Ammo) { CheckedList.Add(self); } if (other is Ammo) { CheckedList.Add(other); } return(other); } } } } return(null); }