/*private void CheckGridCollisions(IColliderEntity thisEntity) * { * foreach ((StaticCollider, Direction) collision in GridCollisionChecker.Instance.HasGridCollisionAt(thisEntity, gridCollisionDirections)) * { * if (!gridCollisions[thisEntity].ContainsKey(collision.Item1)) * { * thisEntity.CollisionStarted(collision.Item1, false); * } * gridCollisions[thisEntity][collision.Item1] = true; * } * }*/ private void CheckCollision(IColliderEntity thisEntity, IColliderEntity otherObject, bool allowOverlap) { if (thisEntity.GetCollisionComponent().CollidesWith(otherObject)) { if (!collisions.ContainsKey(thisEntity) || !collisions[thisEntity].ContainsKey(otherObject)) { thisEntity.CollisionStarted(otherObject, allowOverlap); } collisions[thisEntity][otherObject] = true; } }
private void CheckTriggers(IColliderEntity thisEntity, IGameObject otherObject) { foreach (ITrigger trigger in thisEntity.GetTriggers()) { if (trigger.IsInsideTrigger(otherObject)) { if (!triggers[thisEntity][trigger.GetTag()].ContainsKey(otherObject)) { thisEntity.OnEnterTrigger(trigger.GetTag(), otherObject); } triggers[thisEntity][trigger.GetTag()][otherObject] = true; } } }
public override bool CollidesWith(IColliderEntity otherCollider) { if (otherCollider.GetCollisionComponent().GetType() == ColliderType.BOX) { BoxCollisionComponent otherBox = otherCollider.GetCollisionComponent() as BoxCollisionComponent; return(Position.X <= otherBox.Position.X + otherBox.Width && Position.X + Width >= otherBox.Position.X && Position.Y <= otherBox.Position.Y + otherBox.Height && Position.Y + Height >= otherBox.Position.Y); } else if (otherCollider.GetCollisionComponent().GetType() == ColliderType.CIRCLE) { return(otherCollider.GetCollisionComponent().CollidesWith(owner)); } throw new Exception("Unknown collider type"); }
public List <IColliderEntity> GetCollidesWith(IColliderEntity collider) { List <IColliderEntity> result = new List <IColliderEntity>(); if (collisions.ContainsKey(collider)) { foreach (IColliderEntity e in collisions[collider].Keys) { if (collisions[collider][e]) { result.Add(e); } } } return(result); }
public static void ApplyRepel(IColliderEntity thisCollider, IColliderEntity otherCollider, float repelForceOverride = 0, RepelMode repelMode = RepelMode.BOTH) { float angle = (float)Math.Atan2(otherCollider.GetCollisionComponent().Position.Y - thisCollider.GetCollisionComponent().Position.Y, otherCollider.GetCollisionComponent().Position.X - thisCollider.GetCollisionComponent().Position.X); float repelForce; if (repelForceOverride == 0) { repelForce = Vector2.Distance(thisCollider.GetCollisionComponent().Position, otherCollider.GetCollisionComponent().Position); } else { repelForce = repelForceOverride; } if (repelMode == RepelMode.ONLY_THIS || repelMode == RepelMode.BOTH) { (thisCollider as PhysicalEntity).AddForce(new Vector2((float)-Math.Cos(angle) * repelForce, (float)-Math.Sin(angle) * repelForce)); } if (repelMode == RepelMode.OTHER_COLLIDER_ONLY || repelMode == RepelMode.BOTH) { (otherCollider as PhysicalEntity).AddForce(new Vector2((float)Math.Cos(angle) * repelForce, (float)Math.Sin(angle) * repelForce)); } }
public override bool CollidesWith(IColliderEntity otherCollider) { if (otherCollider.GetCollisionComponent().GetType() == ColliderType.CIRCLE) { //TODO: review if this fast check is needed CircleCollisionComponent other = otherCollider.GetCollisionComponent() as CircleCollisionComponent; if ((Math.Abs(Position.X - otherCollider.GetCollisionComponent().Position.X) > Config.GRID * 2 && Math.Abs(Position.Y - other.Position.Y) > Config.GRID * 2)) { return(false); } maxDistance = Radius + other.Radius; distance = Vector2.Distance(Position, other.Position); return(distance <= maxDistance); } else if (otherCollider.GetCollisionComponent().GetType() == ColliderType.BOX) { BoxCollisionComponent box = otherCollider.GetCollisionComponent() as BoxCollisionComponent; Vector2 closestPoint = new Vector2(Math.Clamp(Position.X, box.Position.X, box.Position.X + box.Width), Math.Clamp(Position.Y, box.Position.Y, box.Position.Y + box.Height)); return(Vector2.DistanceSquared(Position, closestPoint) < Radius * Radius); } throw new Exception("Unknown collider type"); }
public BoxCollisionComponent(IColliderEntity owner, float width, float height, Vector2 positionOffset = default) : base(ColliderType.BOX, owner, positionOffset) { Width = width; Height = height; }
public void Update(IColliderEntity thisEntity = null) { if (changedObjects.Count == 0 && (entities.Count == 0 || toCheckAgainst.Count == 0)) { return; } HandleChangedObjects(); if (!thisEntity.CollisionsEnabled && thisEntity.GetTriggers().Count == 0) { return; } foreach (IColliderEntity otherEntity in toCheckAgainst) { if (thisEntity.Equals(otherEntity)) { continue; } if (thisEntity.GetTriggers().Count > 0 && otherEntity.CanFireTriggers) { CheckTriggers(thisEntity, otherEntity); } if (otherEntity.GetTags().Count == 0 || !otherEntity.CollisionsEnabled) { continue; } bool possibleCollision = false; bool allowOverlap = false; foreach (string tag in otherEntity.GetTags()) { if (thisEntity.GetCollidesAgainst().ContainsKey(tag)) { possibleCollision = true; allowOverlap = thisEntity.GetCollidesAgainst()[tag]; break; } } if (!possibleCollision) { continue; } if (thisEntity.GetCollisionComponent() != null && otherEntity.GetCollisionComponent() != null) { CheckCollision(thisEntity, otherEntity, allowOverlap); } /*if (thisEntity.CheckGridCollisions) * { * CheckGridCollisions(thisEntity); * }*/ } InactivateCollisionsAndTriggers(thisEntity); }
private void InactivateCollisionsAndTriggers(IColliderEntity toUpdate) { foreach (IColliderEntity thisEntity in collisions.Keys) { if (thisEntity.IsDestroyed) { continue; } if (toUpdate != null && !thisEntity.Equals(toUpdate)) { continue; } foreach (IColliderEntity otherObject in collisions[thisEntity].Keys.ToList()) { if (thisEntity.Equals(otherObject)) { continue; } if (!collisions[thisEntity][otherObject]) { thisEntity.CollisionEnded(otherObject); //collisionsToRemove.Add((thisEntity, otherObject)); collisions[thisEntity].Remove(otherObject); } else { collisions[thisEntity][otherObject] = false; } } } foreach (IHasTrigger thisEntity in triggers.Keys) { if (thisEntity.IsDestroyed) { continue; } if (toUpdate != null && !thisEntity.Equals(toUpdate)) { continue; } foreach (string tag in triggers[thisEntity].Keys) { foreach (IHasTrigger otherEntity in triggers[thisEntity][tag].Keys.ToList()) { if (!triggers[thisEntity][tag][otherEntity]) { thisEntity.OnLeaveTrigger(tag, otherEntity); //triggersToRemove.Add((thisEntity, tag, otherEntity)); triggers[thisEntity][tag].Remove(otherEntity); } else { triggers[thisEntity][tag][otherEntity] = false; } } } } /*foreach (IColliderEntity thisEntity in gridCollisions.Keys) * { * foreach (StaticCollider otherCollider in gridCollisions[thisEntity].Keys.ToList()) * { * if(!gridCollisions[thisEntity][otherCollider]) * { * //gridCollisionsToRemove.Add((thisEntity, collider)); * thisEntity.CollisionEnded(otherCollider); * gridCollisions[thisEntity].Remove(otherCollider); * } else * { * gridCollisions[thisEntity][otherCollider] = false; * } * } * }*/ }
public CircleCollisionComponent(IColliderEntity owner, float radius, Vector2 positionOffset = default) : base(ColliderType.CIRCLE, owner, positionOffset) { Radius = radius; }