예제 #1
0
        /*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;
            }
        }
예제 #2
0
 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;
         }
     }
 }
예제 #3
0
        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");
        }
예제 #4
0
        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);
        }
예제 #5
0
        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");
 }
예제 #7
0
 public BoxCollisionComponent(IColliderEntity owner, float width, float height, Vector2 positionOffset = default) : base(ColliderType.BOX, owner, positionOffset)
 {
     Width  = width;
     Height = height;
 }
예제 #8
0
        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);
        }
예제 #9
0
        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;
 }