Exemplo n.º 1
0
        internal void detectBackgroundCollisions(Vector2 currentPosition, Vector2 previousPosition, out Tuple <Vector2, Vector2> closestObjectOut, out Vector2 closestIntersectionOut)
        {
            float collisionRadius = this.GroundPosRadius;
            List <Tuple <Vector2, Vector2> > boundaryLineSegments = new List <Tuple <Vector2, Vector2> >(); //line segments to check collision with sprite
            List <Tuple <Vector2, Vector2> > boundaryCircles      = new List <Tuple <Vector2, Vector2> >(); //circles to check collision with sprite

            //If previous position is same as current position then no collision is possible
            if (previousPosition == currentPosition)
            {
                closestIntersectionOut = new Vector2(float.PositiveInfinity);
                closestObjectOut       = new Tuple <Vector2, Vector2>(new Vector2(float.PositiveInfinity), new Vector2(float.PositiveInfinity));
                return;
            }

            //Add line segments and circles from each tile inside bounding box formed by topLeftMostTile and bottomRightMostTile
            TileList         tileMap         = (This.Game.CurrentLevel as FrostbyteLevel).TileMap;
            Tuple <int, int> topLeftMostTile = new Tuple <int, int>((int)Math.Floor(((Math.Min(previousPosition.X, currentPosition.X) - collisionRadius) / This.CellSize)),   //top left most tile that could possible hit sprite
                                                                    (int)Math.Floor(((Math.Min(previousPosition.Y, currentPosition.Y) - collisionRadius)) / This.CellSize));
            Tuple <int, int> bottomRightMostTile = new Tuple <int, int>((int)Math.Floor((Math.Max(previousPosition.X, currentPosition.X) + collisionRadius) / This.CellSize), //bottom right most tile that could possible hit sprite
                                                                        (int)Math.Floor((Math.Max(previousPosition.Y, currentPosition.Y) + collisionRadius) / This.CellSize));

            for (int x = topLeftMostTile.Item1; x <= bottomRightMostTile.Item1; x++)
            {
                for (int y = topLeftMostTile.Item2; y <= bottomRightMostTile.Item2; y++)
                {
                    Tile tile;
                    tileMap.TryGetValue(x, y, out tile);

                    float tileStartPosX = 0;
                    float tileStartPosY = 0;
                    if (tile.GridCell != null)  //protect collision from tileMap code
                    {
                        tileStartPosX = tile.GridCell.Pos.X;
                        tileStartPosY = tile.GridCell.Pos.Y;
                    }

                    #region Add Tile Boundary Line Segments and Circles to Appropriate Lists
                    switch (tile.Type)
                    {
                    case TileTypes.Wall:                                                                                                                                   //top wall
                        boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize, tileStartPosY + This.CellSize + collisionRadius), //add bottom side of tile
                                                                              new Vector2(tileStartPosX, tileStartPosY + This.CellSize + collisionRadius)));
                        break;

                    case TileTypes.Bottom:                                                                                                                     //bottom wall
                        boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX, tileStartPosY + This.CellSize / 2 - collisionRadius), //add top side of tile
                                                                              new Vector2(tileStartPosX + This.CellSize, tileStartPosY + This.CellSize / 2 - collisionRadius)));
                        break;

                    case TileTypes.SideWall:                                                                                                                   //side wall
                        if (tile.Orientation == Orientations.Up_Left)                                                                                          //right side wall
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX - collisionRadius, tileStartPosY + This.CellSize), //add left side of tile
                                                                                  new Vector2(tileStartPosX - collisionRadius, tileStartPosY)));
                        }
                        else                                                                                                                                   //left side wall
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY), //add left side of tile
                                                                                  new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY + This.CellSize)));
                        }
                        break;

                    case TileTypes.BottomConvexCorner:                                                                                                                                                                     //bottom convex corner wall
                        boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX, tileStartPosY + This.CellSize / 2 - collisionRadius),                                                             //add top side of tile
                                                                              new Vector2(tileStartPosX + This.CellSize, tileStartPosY + This.CellSize / 2 - collisionRadius)));
                        if (tile.Orientation == Orientations.Right)                                                                                                                                                        //right bottom convex corner
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX - collisionRadius, tileStartPosY + This.CellSize),                                                             //add left side of tile
                                                                                  new Vector2(tileStartPosX - collisionRadius, tileStartPosY + This.CellSize / 2)));
                            boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX, tileStartPosY + This.CellSize / 2), new Vector2(float.PositiveInfinity, float.PositiveInfinity)));                 //add top left point of tile
                        }
                        else                                                                                                                                                                                               //left bottom convex corner
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY + This.CellSize / 2),                                         //add right side of tile
                                                                                  new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY + This.CellSize)));
                            boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize, tileStartPosY + This.CellSize / 2), new Vector2(float.PositiveInfinity, float.PositiveInfinity))); //add top right point of tile
                        }
                        break;

                    case TileTypes.ConvexCorner:                                                                                                                                                                       //top convex corner wall
                        boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize, tileStartPosY + This.CellSize + collisionRadius),                                             //add bottom side of tile
                                                                              new Vector2(tileStartPosX, tileStartPosY + This.CellSize + collisionRadius)));
                        if (tile.Orientation == Orientations.Right)                                                                                                                                                    //right top convex corner |_
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX - collisionRadius, tileStartPosY + This.CellSize),                                                         //add left side of tile
                                                                                  new Vector2(tileStartPosX - collisionRadius, tileStartPosY)));
                            boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX, tileStartPosY + This.CellSize), new Vector2(float.PositiveInfinity, float.PositiveInfinity)));                 //add bottom left point of tile
                        }
                        else                                                                                                                                                                                           //left top convex corner _|
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY),                                                         //add right side of tile
                                                                                  new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY + This.CellSize)));
                            boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize, tileStartPosY + This.CellSize), new Vector2(float.PositiveInfinity, float.PositiveInfinity))); //add bottom right point of tile
                        }
                        break;

                    case TileTypes.BottomCorner:                                                                                                                   //bottom concave corner wall
                        if (tile.Orientation == Orientations.Right)                                                                                                //right bottom concave corner _|
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX - collisionRadius, tileStartPosY + This.CellSize / 2), //add left side of tile
                                                                                  new Vector2(tileStartPosX - collisionRadius, tileStartPosY)));

                            //boundaryLineSegments.Add(new Tuple<Vector2, Vector2>(new Vector2((tileStartPosX - collisionRadius) + 1, (tileStartPosY + This.CellSize / 2)), //add left side of tile
                            //                                                     new Vector2((tileStartPosX - collisionRadius) + 1, tileStartPosY + 2)));

                            //boundaryLineSegments.Add(new Tuple<Vector2, Vector2>(new Vector2((tileStartPosX - collisionRadius) + 2, tileStartPosY + This.CellSize / 2), //add left side of tile
                            //                                                     new Vector2((tileStartPosX - collisionRadius) + 2, tileStartPosY + 4)));

                            //boundaryCircles.Add(new Tuple<Vector2, Vector2>(new Vector2(tileStartPosX - 15, tileStartPosY + This.CellSize / 2 - 15 ), new Vector2(float.PositiveInfinity, float.PositiveInfinity))); //add bottom left point of tile
                        }
                        else                                                                                                                                   //left bottom concave corner |_
                        {
                            boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY), //add right side of tile
                                                                                  new Vector2(tileStartPosX + This.CellSize + collisionRadius, tileStartPosY + This.CellSize / 2)));
                        }
                        break;

                    case TileTypes.Corner:     //top concave corner wall
                        //add nothing because it is not possible to hit
                        break;

                    default:
                        break;
                    }
                    #endregion Add Tile Boundary Line Segments and Circles to Appropriate Lists
                }
            }

            foreach (Sprite obstacle in (This.Game.CurrentLevel as FrostbyteLevel).obstacles)
            {
                if (obstacle is Frostbyte.Obstacles.Obstacle)
                {
                    float obstacleStartX = obstacle.Pos.X;
                    float obstacleStartY = obstacle.Pos.Y;
                    boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX + This.CellSize, obstacleStartY + This.CellSize + collisionRadius),                                         //add bottom side of tile
                                                                          new Vector2(obstacleStartX, obstacleStartY + This.CellSize + collisionRadius)));
                    boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX, obstacleStartY - collisionRadius),                                                                         //add top side of tile
                                                                          new Vector2(obstacleStartX + This.CellSize, obstacleStartY - collisionRadius)));
                    boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX - collisionRadius, obstacleStartY + This.CellSize),                                                         //add left side of tile
                                                                          new Vector2(obstacleStartX - collisionRadius, obstacleStartY)));
                    boundaryLineSegments.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX + This.CellSize + collisionRadius, obstacleStartY),                                                         //add right side of tile
                                                                          new Vector2(obstacleStartX + This.CellSize + collisionRadius, obstacleStartY + This.CellSize)));
                    boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX + This.CellSize, obstacleStartY + This.CellSize), new Vector2(float.PositiveInfinity, float.PositiveInfinity))); //add bottom right point of tile
                    boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX, obstacleStartY + This.CellSize), new Vector2(float.PositiveInfinity, float.PositiveInfinity)));                 //add bottom left point of tile
                    boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX + This.CellSize, obstacleStartY), new Vector2(float.PositiveInfinity, float.PositiveInfinity)));                 //add top right point of tile
                    boundaryCircles.Add(new Tuple <Vector2, Vector2>(new Vector2(obstacleStartX, obstacleStartY), new Vector2(float.PositiveInfinity, float.PositiveInfinity)));                                 //add top left point of tile
                }
            }

            //If there are no line segments or circle then there are no possible collisions
            if (boundaryLineSegments.Count == 0 && boundaryCircles.Count == 0)
            {
                closestIntersectionOut = new Vector2(float.PositiveInfinity);
                closestObjectOut       = new Tuple <Vector2, Vector2>(new Vector2(float.PositiveInfinity), new Vector2(float.PositiveInfinity));
                return;
            }

            #region Calculate closest intersection
            Vector2 positiveInfinity = new Vector2(float.PositiveInfinity, float.PositiveInfinity);
            Tuple <Vector2, Vector2> closestObject = new Tuple <Vector2, Vector2>(positiveInfinity, positiveInfinity);
            float   closestDistanceSquared         = float.PositiveInfinity;
            Vector2 closestIntersection            = positiveInfinity;

            foreach (Tuple <Vector2, Vector2> lineSegment in boundaryLineSegments)   //calculate closest line segment
            {
                float tValue = ((lineSegment.Item2.X - lineSegment.Item1.X) * (previousPosition.Y - lineSegment.Item1.Y) - (lineSegment.Item2.Y - lineSegment.Item1.Y) * (previousPosition.X - lineSegment.Item1.X)) /
                               ((lineSegment.Item2.Y - lineSegment.Item1.Y) * (currentPosition.X - previousPosition.X) - (lineSegment.Item2.X - lineSegment.Item1.X) * (currentPosition.Y - previousPosition.Y));

                Vector2 intersection = new Vector2(previousPosition.X + tValue * (currentPosition.X - previousPosition.X), previousPosition.Y + tValue * (currentPosition.Y - previousPosition.Y));

                float distanceSquared = Vector2.DistanceSquared(previousPosition, intersection);

                intersection.X = (float)Math.Round(intersection.X, 4);  //protect against floating point errors
                intersection.Y = (float)Math.Round(intersection.Y, 4);  //protect against floating point errors

                if (distanceSquared >= 0 && distanceSquared <= closestDistanceSquared && (tValue >= 0) &&
                    intersection.X <= Math.Max(lineSegment.Item1.X, lineSegment.Item2.X) && intersection.Y <= Math.Max(lineSegment.Item1.Y, lineSegment.Item2.Y) &&
                    intersection.X >= Math.Min(lineSegment.Item1.X, lineSegment.Item2.X) && intersection.Y >= Math.Min(lineSegment.Item1.Y, lineSegment.Item2.Y))
                {
                    closestDistanceSquared = distanceSquared;
                    closestObject          = lineSegment;
                    closestIntersection    = intersection;
                }
            }

            foreach (Tuple <Vector2, Vector2> circle in boundaryCircles) //calculate closest circle
            {
                Vector2 D = currentPosition - previousFootPos;
                //D.Normalize();
                float A = Vector2.Dot(D, D);
                float B = 2f * Vector2.Dot((previousFootPos - circle.Item1), D);
                float C = Vector2.Dot((previousFootPos - circle.Item1), (previousFootPos - circle.Item1)) - collisionRadius * collisionRadius;

                float discriminant = B * B - 4 * A * C;

                if (discriminant < 0)
                {
                    //there are no intersections
                }
                else if (discriminant == 0)
                {
                    float tValue = (-B) / (2 * A);

                    Vector2 intersection = new Vector2(previousPosition.X + tValue * (currentPosition.X - previousPosition.X), previousPosition.Y + tValue * (currentPosition.Y - previousPosition.Y));

                    float distanceSquared = Vector2.DistanceSquared(previousPosition, intersection);

                    if (distanceSquared >= 0 && distanceSquared <= closestDistanceSquared && tValue >= 0)
                    {
                        closestDistanceSquared = distanceSquared;
                        closestObject          = circle;
                        closestIntersection    = intersection;
                    }
                }
                else //discriminant > 0
                {
                    float tValue1 = (-B + (float)Math.Sqrt(discriminant)) / (2 * A);
                    float tValue2 = (-B - (float)Math.Sqrt(discriminant)) / (2 * A);

                    float closesttValue = 0;
                    if (tValue1 < tValue2 && tValue1 >= 0)
                    {
                        closesttValue = tValue1;
                    }
                    else if (tValue2 >= 0)
                    {
                        closesttValue = tValue2;
                    }
                    else
                    {
                        closesttValue = -1f;
                    }


                    Vector2 intersection = new Vector2(previousPosition.X + closesttValue * (currentPosition.X - previousPosition.X), previousPosition.Y + closesttValue * (currentPosition.Y - previousPosition.Y));

                    float distanceSquared = Vector2.DistanceSquared(previousPosition, intersection);

                    if (distanceSquared >= 0 && distanceSquared <= closestDistanceSquared && (closesttValue >= 0))
                    {
                        closestDistanceSquared = distanceSquared;
                        closestObject          = circle;
                        closestIntersection    = intersection;
                    }
                }
            }
            #endregion Calculate closest intersection


            closestObjectOut       = closestObject;
            closestIntersectionOut = closestIntersection;
            boundaryCircles.Clear();
            boundaryLineSegments.Clear();
        }
Exemplo n.º 2
0
        internal override void Draw(GameTime gameTime, bool drawAfter = false)
        {
            List <Tile> drawLater = new List <Tile>();

            if (TileMap.HasItems)
            {
                #region Draw Base Tiles
                //draw base tiles
                This.Game.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, Camera.GetTransformation(This.Game.GraphicsDevice));

                for (int y = (int)Math.Floor(StartDraw.Y); y < (int)Math.Ceiling(EndDraw.Y); y++)
                {
                    for (int x = (int)Math.Floor(StartDraw.X); x < (int)Math.Ceiling(EndDraw.X); x++)
                    {
                        Tile toDraw;
                        TileMap.TryGetValue(x, y, out toDraw);

                        //toDraw.Draw();
                        if (!(toDraw.Type == TileTypes.Bottom || toDraw.Type == TileTypes.BottomConvexCorner || toDraw.Type == TileTypes.DEFAULT || toDraw.Type == TileTypes.TopArea))
                        {
                            toDraw.Draw();
                        }
                        else
                        {
                            drawLater.Add(toDraw);
                            if (toDraw.Type == TileTypes.Bottom || toDraw.Type == TileTypes.BottomConvexCorner)
                            {
                                //if it's somethign that needs floor draw me a floor piece
                                Tile t = new Tile()
                                {
                                    Type        = TileTypes.Floor,
                                    FloorType   = TileTypes.Floor,
                                    Orientation = Orientations.Down,
                                    GridCell    = toDraw.GridCell,
                                    Theme       = toDraw.Theme,
                                };
                                t.Draw();
                            }
                        }
                    }
                }

                This.Game.spriteBatch.End();

                #endregion
            }
            base.Draw(gameTime, true);

            if (TileMap.HasItems)
            {
                #region draw covering tiles
                This.Game.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, Camera.GetTransformation(This.Game.GraphicsDevice));
                foreach (Tile tile in drawLater)
                {
                    tile.Draw();
                }

                This.Game.spriteBatch.End();
                #endregion draw covering tiles
            }
            #region Draw Static Sprites
            if (staticSprites.Count > 0)
            {
                This.Game.spriteBatch.Begin();

                foreach (var sprite in staticSprites)
                {
                    sprite.Draw(gameTime);
                }

                This.Game.spriteBatch.End();
            }
            #endregion
        }
Exemplo n.º 3
0
        /// <summary>
        /// Check for collision with background and move enemy out of collision with background until no collisions exist
        /// </summary>
        internal void checkBackgroundCollisions()
        {
            if (Vector2.DistanceSquared(previousFootPos, GroundPos) <= .2f)
            {
                GroundPos = previousFootPos;
                return;
            }

            Vector2 positiveInfinity = new Vector2(float.PositiveInfinity, float.PositiveInfinity);
            Tuple <Vector2, Vector2> closestObject = new Tuple <Vector2, Vector2>(positiveInfinity, positiveInfinity);
            Vector2 closestIntersection            = positiveInfinity;
            Vector2 footPos         = this.GroundPos;
            Vector2 originalFootPos = previousFootPos;

            while (Vector2.DistanceSquared(footPos, previousFootPos) > .2f)
            {
                detectBackgroundCollisions(footPos, previousFootPos, out closestObject, out closestIntersection);

                if (closestIntersection == positiveInfinity)
                {
                    break;
                }

                if (closestObject.Item2 == positiveInfinity && closestObject.Item1 != positiveInfinity) //this is for a circle
                {
                    Vector2 A1 = closestObject.Item1 - closestIntersection;
                    Vector2 B1 = footPos - closestIntersection;
                    A1.Normalize();
                    Vector2 tangentToA1                    = new Vector2(-A1.Y, A1.X);
                    float   magnitudeOfTangentToA1         = A1.Length();
                    float   magnitudeOfb                   = B1.Length();
                    float   distFromFootToProjIntersection = Vector2.Dot(tangentToA1, B1) / magnitudeOfTangentToA1;
                    Vector2 newFootPos = closestIntersection + distFromFootToProjIntersection * tangentToA1;
                    if (Vector2.DistanceSquared(previousFootPos, closestIntersection) <= Vector2.DistanceSquared(previousFootPos, footPos) && closestIntersection != positiveInfinity)
                    {
                        Vector2 normal = new Vector2(-A1.X, -A1.Y);
                        normal.Normalize();
                        previousFootPos = closestIntersection + 0.2f * normal;
                        footPos         = newFootPos + 0.2f * normal;
                    }
                    else
                    {
                        previousFootPos = footPos;
                    }
                }
                else //this is for a line segment
                {
                    Vector2 A1 = new Vector2();
                    if (closestObject.Item2 == closestIntersection && closestIntersection != positiveInfinity)
                    {
                        A1 = closestObject.Item1 - closestIntersection;
                    }
                    else
                    {
                        A1 = closestObject.Item2 - closestIntersection;
                    }
                    Vector2 B1 = footPos - closestIntersection;
                    A1.Normalize();
                    float   magnitudeOfa = A1.Length();
                    float   magnitudeOfb = B1.Length();
                    float   distFromFootToProjIntersection = Vector2.Dot(A1, B1) / magnitudeOfa;
                    Vector2 newFootPos = closestIntersection + distFromFootToProjIntersection * A1;
                    if (Vector2.DistanceSquared(previousFootPos, closestIntersection) <= Vector2.DistanceSquared(previousFootPos, footPos) && closestIntersection != positiveInfinity)
                    {
                        Vector2 tangent = closestObject.Item1 - closestObject.Item2;
                        Vector2 normal  = new Vector2(-tangent.Y, tangent.X);
                        normal.Normalize();
                        previousFootPos = closestIntersection + .2f * normal;
                        footPos         = newFootPos + .2f * normal;
                    }
                    else
                    {
                        previousFootPos = footPos;
                    }
                }
            }


            //This takes care of the sprite moving too slow and updates position
            if (Vector2.DistanceSquared(footPos, originalFootPos) >= .2f)
            {
                bool doNotMove = false;

                float            collisionRadius = this.GroundPosRadius;
                Tuple <int, int> topLeftMostTile = new Tuple <int, int>((int)Math.Floor(((footPos.X - collisionRadius) / This.CellSize)),   //top left most tile that could possible hit sprite
                                                                        (int)Math.Floor(((footPos.Y - collisionRadius)) / This.CellSize));
                Tuple <int, int> bottomRightMostTile = new Tuple <int, int>((int)Math.Floor((footPos.X + collisionRadius) / This.CellSize), //bottom right most tile that could possible hit sprite
                                                                            (int)Math.Floor((footPos.Y + collisionRadius) / This.CellSize));
                TileList tileMap = (This.Game.CurrentLevel as FrostbyteLevel).TileMap;
                for (int x = topLeftMostTile.Item1; x <= bottomRightMostTile.Item1; x++)
                {
                    for (int y = topLeftMostTile.Item2; y <= bottomRightMostTile.Item2; y++)
                    {
                        Tile tile;
                        tileMap.TryGetValue(x, y, out tile);

                        if (tile.Type == TileTypes.Floor)
                        {
                            continue;
                        }

                        if ((tile.Type == TileTypes.Bottom || tile.Type == TileTypes.BottomConvexCorner) && !tileCircleCollision(new Vector2(x * 64, y * 64 + 32), new Vector2(x * 64 + 64, y * 64 + 64), footPos, collisionRadius))
                        {
                            continue;
                        }
                        else if (!tileCircleCollision(new Vector2(x * 64, y * 64), new Vector2(x * 64 + 64, y * 64 + 64), footPos, collisionRadius))
                        {
                            continue;
                        }

                        doNotMove = true;
                    }
                }


                if (doNotMove)
                {
                    GroundPos = originalFootPos;
                }
                else
                {
                    GroundPos = footPos;
                }
            }
            else
            {
                this.GroundPos = originalFootPos;
            }
        }