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); }
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)); } }
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); }
/// <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); }