public void Move(GameTime gameTime)
        {
            if (Health <= 0)
            {
                return;
            }
            var timeElapsed = Math.Min(gameTime.ElapsedGameTime.Milliseconds / 1000f, 0.2f);
            var movement    = Velocity * timeElapsed;

            mLastVelocities[mCurrentLastVelocitiesIndex] = Velocity;
            mCurrentLastVelocitiesIndex++;
            mCurrentLastVelocitiesIndex %= mLastVelocities.Length;
            var averageVelocity = mLastVelocities.Aggregate(Vector2.Zero, (current, velocity) => current + velocity);

            Position += movement;
            if (CurrentQuadTree == null)
            {
                Position -= movement;
            }
            else
            {
                Position += QuadTree.ClampPosition(this);
                CurrentQuadTree.UpdateGameObjectPosition(this);
            }

            if (Math.Abs(averageVelocity.Y) > 2 * Math.Abs(averageVelocity.X) && !mOnlyLeftRightDirection)
            {
                if (averageVelocity.Y > 0)
                {
                    mDirection = (int)Directions.Down;
                }
                else
                {
                    mDirection = (int)Directions.Up;
                }
            }
            else if (2 * Math.Abs(averageVelocity.Y) < Math.Abs(averageVelocity.X))
            {
                if (averageVelocity.X > 0)
                {
                    mDirection = (int)Directions.Right;
                }
                else
                {
                    mDirection = (int)Directions.Left;
                }
            }
            else
            {
                if (mDirection == (int)Directions.Down && averageVelocity.Y < 0 ||
                    mDirection == (int)Directions.Up && averageVelocity.Y > 0 ||
                    mDirection == (int)Directions.Right && averageVelocity.X < 0 ||
                    mDirection == (int)Directions.Left && averageVelocity.X > 0)
                {
                    mDirection = (int)GetDirection(averageVelocity);
                }
            }
        }
 private List <ICollidable> GetCollidingObjects(Vector2 position)
 {
     return(CurrentQuadTree.GetCollidingObjects(this, position));
 }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            mCollidingObjects.Clear();
            mNeighborObjects = CurrentQuadTree.GetCollidingObjects(this, 1.5f);
            foreach (var neighbor in mNeighborObjects)
            {
                if (neighbor is BGameObject obj && QuadTree.AreGameObjectsColliding(this, obj))
                {
                    mCollidingObjects.Add(neighbor);
                }
            }

            if (mRandomWalk && !HasPath && sRandom.NextDouble() < RandomWalkChance)
            {
                var distance = 0.5 + mRandomWalkDistance * sRandom.NextDouble();
                var angle    = sRandom.NextDouble() * Math.PI * 2;
                var target   = Position + new Vector2((float)(Math.Cos(angle) * distance),
                                                      (float)(Math.Sin(angle) * distance));
                if (GetCollidingObjects(target).Count == 0)
                {
                    RequestPath(CollisionBoxCenter + new Vector2((float)(Math.Cos(angle) * distance), (float)(Math.Sin(angle) * distance)), loose: true);
                }
            }

            if (!FollowPath())
            {
                mSteering.UpdateSteering(CollisionBoxCenter, mNeighborObjects);
            }
            Velocity += mSteering.GetSteering();
            float collisionFactor = mCollidingObjects.Any() || GetCollidingWaterTiles().Any() ? 2 : 1;

            if (Velocity.Length() > Speed * collisionFactor)
            {
                if (Velocity != Vector2.Zero)
                {
                    Velocity = Vector2.Normalize(Velocity);
                }
                Velocity *= Speed * collisionFactor;
            }

            if (!mLastHealthInitialized)
            {
                mLastHealth            = Health;
                mLastHealthInitialized = true;
            }
            if (mLastHealth - Health > 2 && !mShowBlood)
            {
                mBloodAnimation.Reset();
                mShowBlood     = true;
                mBloodRotation = (float)(sRandom.NextDouble() * 2 * Math.PI);
                mBloodOffset   = new Vector2(Width / 64.0f, (float)sRandom.NextDouble() * Height / 32.0f);
                mBloodScale    = (float)sRandom.NextDouble() + 0.6f;
            }

            if (mBloodAnimation.AnimationFinished)
            {
                mShowBlood = false;
            }

            mBlood      = mBloodAnimation.GetTextureOnce();
            mLastHealth = Health;
        }