Beispiel #1
0
        public void ArriveAtPosition()
        {
            Steerable steerer = new Steerable();

            steerer.MaxSpeed     = 10;
            steerer.Acceleration = 20.02345f;
            steerer.Target       = Vector2.One * 100;
            steerer.Behaviors.Add(new ArriveBehavior());

            float[] targetSpeed = new float[] { 2, 4, 6, 8, 10, 10, 10 };

            for (int i = 0; i < targetSpeed.Length; ++i)
            {
                steerer.Update(ElapsedTime);
                Assert.AreEqual <int>((int)targetSpeed[i], (int)Math.Round(steerer.Speed));
            }

            bool hasStopped      = false;
            bool hasFullyStopped = false;

            for (int i = 0; i < 2000; ++i)
            {
                steerer.Update(ElapsedTime);

                if (hasStopped)
                {
                    Assert.IsTrue(steerer.Speed < steerer.MaxSpeed);
                    if (steerer.Speed <= 0)
                    {
                        hasFullyStopped = true;
                        Assert.IsTrue(Vector2.Distance(Vector2.One * 100, steerer.Position) < 1f);
                    }
                    if (hasFullyStopped)
                    {
                        Assert.IsTrue(steerer.Speed <= float.Epsilon);
                    }
                }
                if ((int)Math.Round(steerer.Speed) != (int)Math.Round(steerer.MaxSpeed))
                {
                    hasStopped = true;
                }
            }
            Assert.IsTrue(hasStopped);
            Assert.IsTrue(hasFullyStopped);
        }
Beispiel #2
0
        public void SeekToPositionMaxAcceleration()
        {
            Steerable steerer = new Steerable();

            steerer.MaxSpeed     = 10;
            steerer.Acceleration = float.MaxValue;
            steerer.Target       = Vector2.One * 1000;
            steerer.Behaviors.Add(new SeekBehavior());

            float[] targetSpeed = new float[] { 10, 10, 10 };

            for (int i = 0; i < targetSpeed.Length; ++i)
            {
                steerer.Update(ElapsedTime);
                Assert.AreEqual <int>((int)targetSpeed[i], (int)Math.Round(steerer.Speed));
            }
        }
Beispiel #3
0
        public void ArriveAtPositionNearby()
        {
            Steerable steerer = new Steerable();

            steerer.MaxSpeed     = 10;
            steerer.Acceleration = 20.02345f;
            steerer.Target       = Vector2.One * 5;
            steerer.Behaviors.Add(new ArriveBehavior());

            bool  hasStopped      = false;
            bool  hasFullyStopped = false;
            float previousSpeed   = float.MinValue;

            for (int i = 0; i < 200; ++i)
            {
                steerer.Update(ElapsedTime);

                if (hasStopped)
                {
                    Assert.IsTrue(steerer.Speed < steerer.MaxSpeed);
                    if (steerer.Speed <= 0)
                    {
                        hasFullyStopped = true;
                        Assert.IsTrue(Vector2.Distance(Vector2.One * 5, steerer.Position) < 0.5f);
                    }
                    if (hasFullyStopped)
                    {
                        Assert.IsTrue(steerer.Speed <= float.Epsilon);
                    }
                }
                if (steerer.Speed < previousSpeed)
                {
                    hasStopped = true;
                }
                previousSpeed = steerer.Speed;
            }
            Assert.IsTrue(hasStopped);
            Assert.IsTrue(hasFullyStopped);
        }
Beispiel #4
0
        /// <summary>
        /// Updates the specified game time.
        /// </summary>
        public void Update(float elapsedTime)
        {
            if (elapsedTime <= 0)
            {
                return;
            }

            Vector2 currentPosition = steerable.Position;

            steerable.Update(elapsedTime);

            if (steerable.Speed > 0 && steerable.Force != Vector2.Zero && State == NavigatorState.Stopped)
            {
                State = NavigatorState.Moving;
                OnStarted();
                return;
            }

            if (steerable.Speed <= 0 && steerable.Force == Vector2.Zero)
            {
                if (State == NavigatorState.Moving)
                {
                    if (waypoints.Count > 0)
                    {
                        MoveTo(waypoints.Dequeue());
                    }
                    else
                    {
                        Stop();
                    }
                }

                return;
            }

            Vector2 nextPosition = steerable.Position;

            // Compute the normal of the terrain. We don't want to our entity
            // to be moving too fast when climbing hills :)
            float   height = 0;
            Vector3 normal = Vector3.Up;

            // Test to see if we reached the border of the ground.
            if (Ground != null && !Ground.TryGetHeightAndNormal(Position, out height, out normal))
            {
                steerable.Position = currentPosition;
                return;
            }

            // We don't want to make the entity moving too physically
            // Moves the agent towards the target.
            Vector3 facing = new Vector3(steerable.forward.X, 0, -steerable.forward.Y);

            // Imagine we are climbing a hill
            Vector3 right     = Vector3.Cross(facing, normal);
            Vector3 direction = Vector3.Cross(normal, right);

            // Adjust player animation speed to avoid sliding artifact
            float increment = Vector3.Dot(direction, facing);

            steerable.Position = Vector2.Lerp(currentPosition, nextPosition, increment);

            realHeight = height;

            UpdateRotation(elapsedTime, facing);

            Transform = Matrix.CreateFromAxisAngle(Vector3.Up, Rotation - MathHelper.PiOver2) *
                        Matrix.CreateTranslation(Position);
        }