/// <summary>Calculates straight line distance to a point on the map</summary> public static double DistanceFrom(this ITakeSpace a, double x, double y) { double distX = a.Position.X - x; double distY = a.Position.Y - y; return(Math.Sqrt(distX * distX + distY * distY)); }
public void Collision(IHumanPlayer player, ITakeSpace other) { var angle = player.AngleAvoiding(other); player.Turn(angle + 2 * Math.Sign(angle)); s = State.Collided; }
/// <summary> /// Returns the distance after which a walker's path, at the current heading, would probably collide with the specified item. /// </summary> /// <returns>A positive distance at which a collision would occur, OR a negative number when no collision would occur.</returns> internal static double CollisionDistance(this IWalker a, ITakeSpace b, double proposedDistanceForward) { if (proposedDistanceForward < 0) { throw new ArgumentException("proposedDistanceForward can't be negative.", "proposedDistanceForward"); } // if the player goes forward here, would they intersect? double distTraveled = 0.0; var h = a.Heading.ToRadians(); double distPerStep = Math.Max(0.05, (Math.Min(WorldConstants.HumanSpeed, WorldConstants.ZombieSpeed) / WorldConstants.StepsPerTurn)); var distXPerStep = distPerStep * Math.Sin(h); var distYPerStep = -distPerStep *Math.Cos(h); var curX = a.Position.X; var curY = a.Position.Y; while (distTraveled < proposedDistanceForward) { if (Intersects(curX, curY, a.Radius, b.Position.X, b.Position.Y, b.Radius)) { return(distTraveled); } distTraveled += distPerStep; curX += distXPerStep; curY += distYPerStep; } return(-1); }
public bool IsInSockRange(ITakeSpace other) { var dist = other.DistanceFrom(this); var sockRange = (WorldConstants.MissileLifespan - 1) * WorldConstants.MissileSpeed; return(dist <= sockRange); }
/// <summary>Calculates how many degrees a zombie/human should turn to avoid a particular thing</summary> public static double AngleAvoiding(this IWalker a, ITakeSpace b) { var angleTo = a.AngleTo(b); if (Math.Abs(angleTo + 90.0) > Math.Abs(angleTo - 90.0)) { return((angleTo - 90.0).MinimumAngle()); } return((angleTo + 90.0).MinimumAngle()); }
/// <summary>Calculates how many degrees a zombie/human should turn to face away from a particular thing</summary> public static double AngleAwayFrom(this IWalker a, ITakeSpace b) { var angleTo = a.AngleTo(b); if (angleTo + 180.0 >= 180.0) { return((180.0 - angleTo).MinimumAngle()); } return((angleTo + 180.0).MinimumAngle()); }
public void Collision(IHumanPlayer player, ITakeSpace other) { if (player.Movement == MoveState.Moving) { return; // nothing to do? } double angle = player.AngleAvoiding(other); player.Turn(angle); //Console.WriteLine("Turning {0} degrees to avoid obstacle.", angle); hasCollidedLastTurn = true; }
public void Collision(IZombiePlayer player, ITakeSpace other) { double angle = player.AngleAvoiding(other); if (Math.Abs(angle) < 0.05) { // Turn directly the other way, and move off. angle = player.AngleAwayFrom(other); } if (ThinkOutLoud) { Console.WriteLine("Collided with {0}! Turning {1} degrees to avoid.", other, angle); } player.Turn(angle); collided = true; }
/// <summary>Calculates how many degrees a zombie/human should turn to face a particular thing</summary> /// <returns>The angle to turn. A negative number means a left turn, a positive number means a right turn.</returns> public static double AngleTo(this IWalker a, ITakeSpace b) { /* * Thanks to Chris for inspiring me to fix this; my version didn't work, and his version didn't work either. * (Atleast for what Yusuf was wanting them to do. XD ) * * GreedyHuman fails on the Plentiful map with either implementation. * On the other hand, this version works well, gives left-or-right turns, and it's short & clean too. */ double distToTarget = a.DistanceFrom(b); double curHeading = (90.0 - a.Heading).ToRadians(); // relative to the x-axis // the heading intersects a circle with radius /distAB/ at some point, call it C. Find that point of intersection. // x = xA + r cos (heading) // y = yA + r sin (heading) double xC = a.Position.X + distToTarget * Math.Cos(curHeading); double yC = a.Position.Y + -distToTarget *Math.Sin(curHeading); // let the built-in vector math sort it all out :-). Vector vHeading = new Vector(a.Position.X - xC, a.Position.Y - yC); Vector vTarget = new Vector(a.Position.X - b.Position.X, a.Position.Y - b.Position.Y); return(Vector.AngleBetween(vHeading, vTarget).MinimumAngle()); }
public void Collision(IHumanPlayer player, ITakeSpace other) { throw new NotImplementedException(); }
/// <summary> /// Returns true if the player is close enough to interact with (e.g., bite or take socks from) the specified thing on the map /// </summary> public static bool IsCloseEnoughToInteractWith(this IWalker a, ITakeSpace b) { return(a.DistanceFrom(b) - a.Radius - b.Radius <= WorldConstants.InteractionDistance); }
/// <summary>Calculates straight line distance between two things on the map</summary> public static double DistanceFrom(this ITakeSpace a, ITakeSpace b) { return(DistanceFrom(a, b.Position.X, b.Position.Y)); }
internal static bool Intersects(this ITakeSpace a, double bx, double by, double bradius) { return(Intersects(a.Position.X, a.Position.Y, a.Radius, bx, by, bradius)); }
/// <summary> /// Returns true if two items on the map overlap /// </summary> public static bool Intersects(this ITakeSpace a, ITakeSpace b) { return(Intersects(a.Position.X, a.Position.Y, a.Radius, b.Position.X, b.Position.Y, b.Radius)); }
public void Collision(IHumanPlayer player, ITakeSpace other) { }
public void Collision(IHumanPlayer player, ITakeSpace other) { //Console.WriteLine("random human: I collided with {0}", other); player.Turn(player.AngleAvoiding(other)); }