Defines the collision properties and methods to check collisions for an Entity.
Наследование: SceneNode
Пример #1
0
 /// <summary>
 /// Add a CollisionUnit to the Pharaoh's control.
 /// </summary>
 /// <param name="unit">The CollisionUnit to add.</param>
 public void AddCollisionUnit(CollisionUnit unit)
 {
     if (ContentUtil.LoadingBuilders || unit == null)
     {
         return;
     }
     CollisionChief chief = CollisionChief.GetInstance();
     chief.AddCollisionUnit(unit);
     chief.UpdateUnit(unit);
 }
Пример #2
0
        /// <summary>
        /// Add a new CollisionUnit to the CollisionChief.
        /// </summary>
        /// <param name="unit">The CollisionUnit to add to the CollisionChief.</param>
        public void AddCollisionUnit(CollisionUnit unit)
        {
            Vector2 circleCenter;
            int circleRadius;
            Vector2 lineStart;
            Vector2 lineEnd;
            Point topLeftCell;
            Point bottomRightCell;

            if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE)
            {
                circleCenter = unit.GetCircleCenter();
                circleRadius = unit.GetCircleRadius();

                // put in appropriate cells
                topLeftCell = CalculateCircleTopLeftCell(circleCenter, circleRadius);
                bottomRightCell = CalculateCircleBottomRightCell(circleCenter, circleRadius);

                for (int i = topLeftCell.X; i <= bottomRightCell.X; i++)
                {
                    for (int j = topLeftCell.Y; j <= bottomRightCell.Y; j++)
                    {
                        mCollisionGrid.Cells[i,j].AddCollisionUnit(unit);
                    }
                }

            }
            else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_LINE)
            {
                lineStart = unit.GetLineStart();
                lineEnd = unit.GetLineEnd();

                // TODO: put in appropriate cells

            }
            else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_BOX)
            {
                topLeftCell = CalculateCellPosition(unit.GetUpperLeft());
                bottomRightCell = CalculateCellPosition(unit.GetLowerRight());

                for (int i = topLeftCell.X; i <= bottomRightCell.X; i++)
                {
                    for (int j = topLeftCell.Y; j <= bottomRightCell.Y; j++)
                    {
                        mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                    }
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Add a new CollisionUnit to this CollisionCell.
 /// </summary>
 /// <param name="unit">The CollisionUnit to add.</param>
 public void AddCollisionUnit(CollisionUnit unit)
 {
     collisionMembers.Add(unit);
 }
Пример #4
0
 private void InitializeCommonStuff(Entity owner, Texture2D collisionMask, bool bUsePixelCollision)
 {
     mOwner = owner;
     mCollisionMask = collisionMask;
     bPixelCollision = bUsePixelCollision;
     bNeedsUpdate = true;
     mCollisions = new List<CollisionUnit>();
     mCheckedUnits = new List<CollisionUnit>();
     mLastCheckedBy = null;
     mCheckTimeStamp = 0;
     bCollisionsChanged = false;
     mCollisionTimeStamp = 0;
     mFullCheckTimeStamp = 0;
     mSolid = true;
 }
Пример #5
0
 /// <summary>
 /// Update the collision status between this and the <paramref name="other"/> CollisionUnit.
 /// </summary>
 /// <param name="other">The CollisionUnit to update.</param>
 public void UpdateCollisionsWith(CollisionUnit other)
 {
     if (CollidesWith(other))
     {
         AddCollision(other);
         other.AddCollision(this);
     }
     else
     {
         RemoveCollision(other);
         other.RemoveCollision(this);
     }
 }
Пример #6
0
 /// <summary>
 /// Set the last collision unit to be checked with this collision unit.
 /// </summary>
 /// <param name="unit">The last checked collision unit.</param>
 public void SetLastCheckedBy(CollisionUnit unit)
 {
     mLastCheckedBy = unit;
 }
Пример #7
0
        /// <summary>
        /// Remove a collision with another unit.
        /// </summary>
        /// <param name="other">The CollisionUnit to remove the collision from.</param>
        public void RemoveCollision(CollisionUnit other)
        {
            if (mCollisions.Remove(other))
            {
                bCollisionsChanged = true;
            }

            bHasCollisions = mCollisions.Count > 0;
        }
Пример #8
0
        /// <summary>
        /// Scale a CollisionUnit by the given amount.
        /// </summary>
        /// <param name="unit">The CollisionUnit to scale.</param>
        /// <param name="scale">The delta scale to perform on the CollisionUnit.</param>
        public void ScaleCollisionUnit(CollisionUnit unit, Vector2 scale)
        {
            int oldCircleRadius;
            int newCircleRadius;
            Vector2 circleCenter;
            Vector2 oldLineStart;
            Vector2 oldLineEnd;
            Point oldTopLeftCell;
            Point oldBottomRightCell;
            Point newTopLeftCell;
            Point newBottomRightCell;
            bool scaleFromCenter = false;

            if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE || unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_BOX)
            {
                if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE)
                {
                    oldCircleRadius = unit.GetCircleRadius();
                    //newCircleRadius = (int)(unit.GetCircleRadius() * ((scale.X + scale.Y) / 2));
                    //newCircleRadius = (int)(unit.GetCircleRadius() + unit.GetCircleRadius() * ((scale.X + scale.Y) / 2));
                    newCircleRadius = (int)(unit.GetCircleRadius() + ((scale.X + scale.Y) / 2));
                    circleCenter = unit.GetCircleCenter();

                    // calculate containing cells
                    oldTopLeftCell = CalculateCircleTopLeftCell(circleCenter, oldCircleRadius);
                    oldBottomRightCell = CalculateCircleBottomRightCell(circleCenter, oldCircleRadius);

                    newTopLeftCell = CalculateCircleTopLeftCell(circleCenter, newCircleRadius);
                    newBottomRightCell = CalculateCircleBottomRightCell(circleCenter, newCircleRadius);
                }
                else
                {
                    Vector2 point1 = unit.GetUpperLeft();
                    Vector2 point2 = unit.GetLowerRight();
                    int oldWidth = unit.GetWidth();
                    int oldHeight = unit.GetHeight();
                    //int xChange = (int)(((oldWidth * scale.X) - oldWidth) / 2);
                    //int yChange = (int)(((oldHeight * scale.Y) - oldHeight) / 2);
                    //int xChange = (int)(oldWidth * scale.X / 2);
                    //int yChange = (int)(oldHeight * scale.Y / 2);
                    int xChange = (int)scale.X;
                    int yChange = (int)scale.Y;

                    // scale from center
                    if (scaleFromCenter)
                    {
                        point1.X -= xChange;
                        point1.Y -= yChange;

                        point2.X += xChange;
                        point2.Y += yChange;
                    }
                    else
                    {
                        // scale with top left stationary
                        point2.X += xChange * 2;
                        point2.Y += yChange * 2;
                    }

                    oldTopLeftCell = CalculateCellPosition(unit.GetUpperLeft());
                    oldBottomRightCell = CalculateCellPosition(unit.GetLowerRight());

                    newTopLeftCell = CalculateCellPosition(point1);
                    newBottomRightCell = CalculateCellPosition(point2);
                }

                //if (scale.X < 1)
                if (scale.X < 0)
                {
                    for (int j = oldTopLeftCell.Y; j <= oldBottomRightCell.Y; j++)
                    {
                        // remove left
                        for (int i = oldTopLeftCell.X; i < newTopLeftCell.X; i++)
                        {
                            mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                        }

                        // remove right
                        for (int i = newBottomRightCell.X + 1; i <= oldBottomRightCell.X; i++)
                        {
                            mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                        }
                    }

                    //if (scale.Y < 1)
                    if (scale.Y < 0)
                    {
                        for (int i = newTopLeftCell.X; i <= newBottomRightCell.X; i++)
                        {
                            // remove top
                            for (int j = oldTopLeftCell.Y; j < newTopLeftCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                            }

                            // remove bottom
                            for (int j = newBottomRightCell.Y + 1; j <= oldBottomRightCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                            }
                        }
                    }
                    //else if (scale.Y > 1)
                    else if (scale.Y > 0)
                    {
                        for (int i = newTopLeftCell.X; i <= newBottomRightCell.X; i++)
                        {
                            // add top
                            for (int j = newTopLeftCell.Y; j < oldTopLeftCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                            }

                            // add bottom
                            for (int j = oldBottomRightCell.Y + 1; j <= newBottomRightCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                            }
                        }
                    }
                }
                //else if (scale.X > 1)
                else if (scale.X > 0)
                {
                    for (int j = newTopLeftCell.Y; j <= newBottomRightCell.Y; j++)
                    {
                        // add left
                        for (int i = newTopLeftCell.X; i < oldTopLeftCell.X; i++)
                        {
                            mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                        }

                        // add right
                        for (int i = oldBottomRightCell.X + 1; i <= newBottomRightCell.X; i++)
                        {
                            mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                        }
                    }

                    //if (scale.Y < 1)
                    if (scale.Y < 0)
                    {
                        for (int i = oldTopLeftCell.X; i <= oldBottomRightCell.X; i++)
                        {
                            // remove top
                            for (int j = oldTopLeftCell.Y; j < newTopLeftCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                            }

                            // remove bottom
                            for (int j = newBottomRightCell.Y + 1; j <= oldBottomRightCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                            }
                        }
                    }
                    //else if (scale.Y > 1)
                    else if (scale.Y > 0)
                    {
                        for (int i = oldTopLeftCell.X; i <= oldBottomRightCell.X; i++)
                        {
                            // add top
                            for (int j = newTopLeftCell.Y; j < oldTopLeftCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                            }

                            // add bottom
                            for (int j = oldBottomRightCell.Y + 1; j <= newBottomRightCell.Y; j++)
                            {
                                mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                            }
                        }
                    }
                }
            }
            else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_LINE)
            {
                oldLineStart = unit.GetLineStart();
                oldLineEnd = unit.GetLineEnd();

                // TODO: put in appropriate cells

            }
        }
Пример #9
0
        /// <summary>
        /// Add a collision to with another unit.
        /// </summary>
        /// <param name="other">The CollisionUnit that was collided with.</param>
        public void AddCollision(CollisionUnit other)
        {
            if (!mCollisions.Contains(other))
            {
                mCollisions.Add(other);

                bCollisionsChanged = true;

                if (!bHasCollisions)
                {
                    bHasCollisions = true;
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Add a bounce between two CollisionUnits based on the velocity.
        /// </summary>
        /// <param name="unit">The main collision unit involved in the "bounce".</param>
        /// <param name="other">The secondary collision unit involved in the "bounce".</param>
        public void AddBounce(CollisionUnit unit, CollisionUnit other)
        {
            Vector2 unitCircleCenter;
            Vector2 otherCircleCenter;
            int unitRadius;
            int otherRadius;
            Vector2 oldVelocity;

            Vector2 norm;
            Vector2 unitNorm;
            Vector2 unitTan = new Vector2();
            Vector2 oldVelocityOther = new Vector2(0, 0);
            float velocityNorm;
            float velocityTan;
            float velocityNormOther;
            float velocityTanOther;
            float newVelocityScalar;
            float newVelocityScalarOther;
            Vector2 newVelocityNorm;
            Vector2 newVelocityNormOther;
            Vector2 newVelocityTan;
            Vector2 newVelocityTanOther;
            Vector2 newVelocity;
            Vector2 newVelocityOther;
            float mass = 1;
            float massOther = 10000;
            Vector2 velocityDiff;

            if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE)
            {
                unitCircleCenter = unit.GetCircleCenter();
                unitRadius = unit.GetCircleRadius();

                otherCircleCenter = other.GetCircleCenter();
                otherRadius = other.GetCircleRadius();

                oldVelocity = mVelocity;

                ////////////////

                norm = otherCircleCenter - unitCircleCenter;
                unitNorm = norm / ((float)Math.Sqrt(norm.X * norm.X + norm.Y * norm.Y));
                unitTan.X = unitNorm.Y * -1;
                unitTan.Y = unitNorm.X;

                velocityNorm = Vector2.Dot(unitNorm, oldVelocity);
                velocityTan = Vector2.Dot(unitTan, oldVelocity);
                velocityNormOther = Vector2.Dot(unitNorm, oldVelocityOther);
                velocityTanOther = Vector2.Dot(unitTan, oldVelocityOther);

                newVelocityScalar = (velocityNorm * (mass - massOther) + 2 * massOther * velocityNormOther) / (mass + massOther);
                newVelocityScalarOther = (velocityNormOther * (massOther - mass) + 2 * mass * velocityNorm) / (mass + massOther);

                newVelocityNorm = newVelocityScalar * unitNorm;
                newVelocityNormOther = newVelocityScalarOther * unitNorm;

                newVelocityTan = velocityTan * unitTan;
                newVelocityTanOther = velocityTanOther * unitTan;

                newVelocity = newVelocityNorm + newVelocityTan;
                newVelocityOther = newVelocityNormOther + newVelocityTanOther;

                newVelocity *= 0.99f;

                velocityDiff = newVelocity - mVelocity;
                mVelocity = newVelocity;

                // some fudge
                //if (velocityDiff.X > 1 || velocityDiff.X < -1 || velocityDiff.Y > 1 || velocityDiff.Y < -1)
                //{
                    mOwner.Translate(0.04f * (unitCircleCenter.X - otherCircleCenter.X), 0.04f * (unitCircleCenter.Y - otherCircleCenter.Y));
                //}
            }
            else
            {
                newVelocity = mVelocity * -0.8f;
                velocityDiff = newVelocity - mVelocity;
                mVelocity = newVelocity;
                unitCircleCenter = unit.GetCircleCenter();
                otherCircleCenter = unit.GetCollisionPoint(other);

                //if (velocityDiff.X > 1 || velocityDiff.X < -1 || velocityDiff.Y > 1 || velocityDiff.Y < -1)
                //{
                    mOwner.Translate(0.04f * (unitCircleCenter.X - otherCircleCenter.X), 0.04f * (unitCircleCenter.Y - otherCircleCenter.Y));
                //}
            }
        }
Пример #11
0
 /// <summary>
 /// Add a CollisionUnit to associate with this PhysicsBaby.
 /// </summary>
 /// <param name="unit">The CollisionUnit to add.</param>
 public void AddCollisionUnit(CollisionUnit unit)
 {
     mCollisionUnits.Add(unit);
 }
Пример #12
0
 /// <summary>
 /// Add a specific CollisionUnit to a queue of units to update.
 /// </summary>
 /// <param name="unit">The CollisionUnit to get updated.</param>
 public void UpdateUnit(CollisionUnit unit)
 {
     mUnitsToUpdate.Add(unit);
 }
Пример #13
0
        /// <summary>
        /// Translate a CollisionUnit by the given amount.
        /// </summary>
        /// <param name="unit">The CollisionUnit to translate.</param>
        /// <param name="translation">The delta translation to perform on the CollisionUnit.</param>
        public void TranslateCollisionUnit(CollisionUnit unit, Vector2 translation)
        {
            int circleRadius;
            Vector2 oldCircleCenter;
            Vector2 oldLineStart;
            Vector2 oldLineEnd;
            Point oldTopLeftCell;
            Point oldBottomRightCell;
            Vector2 newCircleCenter;
            Point newTopLeftCell;
            Point newBottomRightCell;

            if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE || unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_BOX)
            {
                if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE)
                {
                    circleRadius = unit.GetCircleRadius();
                    oldCircleCenter = unit.GetCircleCenter();
                    newCircleCenter = oldCircleCenter + translation;

                    // calculate containing cells
                    oldTopLeftCell = CalculateCircleTopLeftCell(oldCircleCenter, circleRadius);
                    oldBottomRightCell = CalculateCircleBottomRightCell(oldCircleCenter, circleRadius);

                    newTopLeftCell = CalculateCircleTopLeftCell(newCircleCenter, circleRadius);
                    newBottomRightCell = CalculateCircleBottomRightCell(newCircleCenter, circleRadius);
                }
                else
                {
                    oldTopLeftCell = CalculateCellPosition(unit.GetUpperLeft());
                    oldBottomRightCell = CalculateCellPosition(unit.GetLowerRight());

                    newTopLeftCell = CalculateCellPosition(unit.GetUpperLeft() + translation);
                    newBottomRightCell = CalculateCellPosition(unit.GetLowerRight() + translation);
                }

                // remove from cells no longer within and add to new cells that unit is within
                if (translation.X > 0)
                {
                    // remove
                    for (int i = oldTopLeftCell.X; i < newTopLeftCell.X && i <= oldBottomRightCell.X; i++)
                    {
                        for (int j = oldTopLeftCell.Y; j <= oldBottomRightCell.Y; j++)
                        {
                            mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                        }
                    }

                    // add
                    int minStart = oldBottomRightCell.X + 1;
                    if (minStart < newTopLeftCell.X)
                    {
                        minStart = newTopLeftCell.X;
                    }

                    for (int i = minStart; i <= newBottomRightCell.X; i++)
                    {
                        for (int j = newTopLeftCell.Y; j <= newBottomRightCell.Y; j++)
                        {
                            mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                        }
                    }
                }
                else if (translation.X < 0)
                {
                    // remove
                    int minStart = newBottomRightCell.X + 1;
                    if (minStart < oldTopLeftCell.X)
                    {
                        minStart = oldTopLeftCell.X;
                    }

                    for (int i = minStart; i <= oldBottomRightCell.X; i++)
                    {
                        for (int j = oldTopLeftCell.Y; j <= oldBottomRightCell.Y; j++)
                        {
                            mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
                        }
                    }

                    // add
                    for (int i = newTopLeftCell.X; i < oldTopLeftCell.X && i <= newBottomRightCell.X; i++)
                    {
                        for (int j = newTopLeftCell.Y; j <= newBottomRightCell.Y; j++)
                        {
                            mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
                        }
                    }
                }

                if (translation.Y > 0)
                {
                    // remove
                    for (int i = oldTopLeftCell.Y; i < newTopLeftCell.Y && i <= oldBottomRightCell.Y; i++)
                    {
                        for (int j = oldTopLeftCell.X; j <= oldBottomRightCell.X; j++)
                        {
                            mCollisionGrid.Cells[j, i].RemoveCollisionUnit(unit);
                        }
                    }

                    // add
                    int minStart = oldBottomRightCell.Y + 1;
                    if (minStart < newTopLeftCell.Y)
                    {
                        minStart = newTopLeftCell.Y;
                    }

                    for (int i = minStart; i <= newBottomRightCell.Y; i++)
                    {
                        // avoid double adds
                        if (translation.X > 0)
                        {
                            for (int j = newTopLeftCell.X; j <= oldBottomRightCell.X; j++)
                            {
                                mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
                            }
                        }
                        else
                        {
                            for (int j = oldTopLeftCell.X; j <= newBottomRightCell.X; j++)
                            {
                                mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
                            }
                        }
                    }
                }
                else if (translation.Y < 0)
                {
                    // remove
                    int minStart = newBottomRightCell.Y + 1;
                    if (minStart < oldTopLeftCell.Y)
                    {
                        minStart = oldTopLeftCell.Y;
                    }

                    for (int i = minStart; i <= oldBottomRightCell.Y; i++)
                    {
                        for (int j = oldTopLeftCell.X; j <= oldBottomRightCell.X; j++)
                        {
                            mCollisionGrid.Cells[j, i].RemoveCollisionUnit(unit);
                        }
                    }

                    // add
                    for (int i = newTopLeftCell.Y; i < oldTopLeftCell.Y && i <= newBottomRightCell.Y; i++)
                    {
                        // avoid double adds
                        if (translation.X > 0)
                        {
                            for (int j = newTopLeftCell.X; j <= oldBottomRightCell.X; j++)
                            {
                                mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
                            }
                        }
                        else
                        {
                            for (int j = oldTopLeftCell.X; j <= newBottomRightCell.X; j++)
                            {
                                mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
                            }
                        }
                    }
                }

            }
            else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_LINE)
            {
                oldLineStart = unit.GetLineStart();
                oldLineEnd = unit.GetLineEnd();

                // TODO: put in appropriate cells

            }
        }
Пример #14
0
 /// <summary>
 /// Remove a CollisionUnit from this CollisionCell.
 /// </summary>
 /// <param name="unit">The CollisionUnit to remove.</param>
 public void RemoveCollisionUnit(CollisionUnit unit)
 {
     collisionMembers.Remove(unit);
 }
Пример #15
0
        /// <summary>
        /// Determine if this CollisionUnit collides with another.
        /// </summary>
        /// <param name="other">The CollisionUnit to check for collision.</param>
        /// <returns><code>true</code> if this collision unit collides with the <paramref name="other"/> CollisionUnit, <code>false</code> if otherwise.</returns>
        public bool CollidesWith(CollisionUnit other)
        {
            Vector2 otherCircleCenter;
            int otherCircleRadius;
            float dX;
            float dY;
            float dist;
            Vector2 otherUpperLeft;
            Vector2 otherLowerRight;

            mCheckedUnits.Add(other);

            if (mCollisionType == CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionType.COLLISION_CIRCLE)
            {
                otherCircleCenter = other.GetCircleCenter();
                otherCircleRadius = other.GetCircleRadius();

                dX = mCircleCenter.X - otherCircleCenter.X;
                dY = mCircleCenter.Y - otherCircleCenter.Y;
                dist = (dX * dX) + (dY * dY);

                // (radius + radius)^2 instead of more expensive squareRoot(dist)
                return (dist <= (mCircleRadius + otherCircleRadius) * (mCircleRadius + otherCircleRadius));
            }
            else if (mCollisionType == CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionType.COLLISION_BOX)
            {
                return CircleBoxCollision(mCircleCenter, mCircleRadius, other.GetUpperLeft(), other.GetLowerRight());
            }
            else if (mCollisionType == CollisionType.COLLISION_BOX && other.GetCollisionType() == CollisionType.COLLISION_CIRCLE)
            {
                return CircleBoxCollision(other.GetCircleCenter(), other.GetCircleRadius(), mPoint1, mPoint2);
            }
            else if (mCollisionType == CollisionType.COLLISION_BOX && other.GetCollisionType() == CollisionType.COLLISION_BOX)
            {
                otherUpperLeft = other.GetUpperLeft();
                otherLowerRight = other.GetLowerRight();

                return (mPoint1.X <= otherLowerRight.X && mPoint1.Y <= otherLowerRight.Y && otherUpperLeft.X <= mPoint2.X && otherUpperLeft.Y <= mPoint2.Y);
            }

            // TODO: other collision types - line, pixel

            return false;
        }
Пример #16
0
        protected static Vector2 GetIntersectionRectangle(CollisionUnit A, CollisionUnit B)
        {
            // Calculate half sizes.
            float halfWidthA = (A.GetLowerRight().X - A.GetUpperLeft().X) / 2.0f;
            float halfHeightA = (A.GetLowerRight().Y - A.GetUpperLeft().Y) / 2.0f;
            float halfWidthB = (B.GetLowerRight().X - B.GetUpperLeft().X) / 2.0f;
            float halfHeightB = (B.GetLowerRight().Y - B.GetUpperLeft().Y) / 2.0f;

            // Calculate centers.
            Vector2 centerA = new Vector2(A.GetUpperLeft().X + halfWidthA, A.GetUpperLeft().Y + halfHeightA);
            Vector2 centerB = new Vector2(B.GetUpperLeft().X + halfWidthB, B.GetUpperLeft().Y + halfHeightB);

            // Calculate current and minimum-non-intersecting distances between centers.
            float distanceX = centerA.X - centerB.X;
            float distanceY = centerA.Y - centerB.Y;
            float minDistanceX = halfWidthA + halfWidthB;
            float minDistanceY = halfHeightA + halfHeightB;

            // If we are not intersecting at all, return (0, 0).
            if (Math.Abs(distanceX) >= minDistanceX || Math.Abs(distanceY) >= minDistanceY)
                return Vector2.Zero;

            // Calculate and return intersection depths.
            float depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
            float depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;
            return new Vector2(depthX, depthY);
        }
Пример #17
0
        /// <summary>
        /// Get the point of collision with the <paramref name="other"/> CollisionUnit. This does not do any real collision checks so the returned value might not be the actual collision point.
        /// </summary>
        /// <param name="other">The CollisionUnit to get the collision point from.</param>
        /// <returns>A Vector2 representing the collision point.</returns>
        public Vector2 GetCollisionPoint(CollisionUnit other)
        {
            Vector2 otherCircleCenter;
            int otherCircleRadius;
            Vector2 boxUpperLeft;
            Vector2 boxLowerRight;
            float dX;
            float dY;
            float ratio;
            Vector2 collisionPoint = new Vector2(-1, -1);

            if (mCollisionType == CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionType.COLLISION_CIRCLE)
            {
                otherCircleCenter = other.GetCircleCenter();
                otherCircleRadius = other.GetCircleRadius();

                dX = otherCircleCenter.X - mCircleCenter.X;
                dY = otherCircleCenter.Y - mCircleCenter.Y;

                ratio = ((float)mCircleRadius) / (mCircleRadius + otherCircleRadius);

                dX *= ratio;
                dY *= ratio;

                collisionPoint = new Vector2(mCircleCenter.X + dX, mCircleCenter.Y + dY);
            }
            else if ((mCollisionType == CollisionType.COLLISION_CIRCLE && other.GetCollisionType() == CollisionType.COLLISION_BOX)
                    || (mCollisionType == CollisionType.COLLISION_BOX && other.GetCollisionType() == CollisionType.COLLISION_CIRCLE))
            {
                if (mCollisionType == CollisionType.COLLISION_CIRCLE)
                {
                    otherCircleCenter = mCircleCenter;
                    otherCircleRadius = mCircleRadius;
                    boxUpperLeft = other.GetUpperLeft();
                    boxLowerRight = other.GetLowerRight();
                }
                else
                {
                    otherCircleCenter = other.GetCircleCenter();
                    otherCircleRadius = other.GetCircleRadius();
                    boxUpperLeft = mPoint1;
                    boxLowerRight = mPoint2;
                }

                if (otherCircleCenter.X > boxLowerRight.X)
                {
                    if (otherCircleCenter.Y > boxLowerRight.Y)
                    {
                        collisionPoint = boxLowerRight;
                    }
                    else if (otherCircleCenter.Y < boxUpperLeft.Y)
                    {
                        collisionPoint = new Vector2(boxLowerRight.X, boxUpperLeft.Y);
                    }
                    else
                    {
                        collisionPoint = new Vector2(otherCircleCenter.X - otherCircleRadius, otherCircleCenter.Y);
                    }
                }
                else if (otherCircleCenter.X < boxUpperLeft.X)
                {
                    if (otherCircleCenter.Y > boxLowerRight.Y)
                    {
                        collisionPoint = new Vector2(boxUpperLeft.X, boxLowerRight.Y);
                    }
                    else if (otherCircleCenter.Y < boxUpperLeft.Y)
                    {
                        collisionPoint = boxUpperLeft;
                    }
                    else
                    {
                        collisionPoint = new Vector2(otherCircleCenter.X + otherCircleRadius, otherCircleCenter.Y);
                    }
                }
                else if (otherCircleCenter.Y > boxLowerRight.Y)
                {
                    collisionPoint = new Vector2(otherCircleCenter.X, otherCircleCenter.Y - otherCircleRadius);
                }
                else if (otherCircleCenter.Y < boxUpperLeft.Y)
                {
                    collisionPoint = new Vector2(otherCircleCenter.X, otherCircleCenter.Y + otherCircleRadius);
                }
                else
                {
                    // inside
                    collisionPoint = otherCircleCenter;
                }
            }

            return collisionPoint;
        }
Пример #18
0
        /// <summary>
        /// Set the collision unit for this Entity.
        /// </summary>
        /// <param name="unit">The collision unit to set for this Entity.</param>
        public void SetCollisionUnit(CollisionUnit unit)
        {
            if (unit != null && unit != mCollisionUnit)
            {
                if (mCollisionUnit != null)
                {
                    //Cleanup collision units
                    //TODO
                }
                mCollisionUnit = unit;
                mPhysBaby.AddCollisionUnit(unit);
                AddChild(unit);

                PhysicsPharaoh.GetInstance().AddCollisionUnit(unit);
            }
        }
Пример #19
0
 /// <summary>
 /// Rotate a CollisionUnit by the given amount.
 /// </summary>
 /// <param name="unit">The CollisionUnit to rotate.</param>
 /// <param name="rotation">The delta rotation to perform on the CollisionUnit (in radians).</param>
 public void RotateCollisionUnit(CollisionUnit unit, float rotation)
 {
     // TODO
 }