/// <summary> /// Makes the peon avoid terrain. THIS IS F****D, DON'T USE IT /// </summary> /// <param name="terrain"></param> /// <returns></returns> public Vector2 avoidTerrain(Terrain terrain, float lookaheadDistance) { // we shouldn't be colliding now Debug.Assert(!terrain.CheckCollision(position)); if (velocity == Vector2.Zero) { if (terrain.CheckCollision(position)) { throw new Exception("peon stuck in terrain w/ 0 velocity"); } return(Vector2.Zero); } Vector2 nextPos = position + Vector2.Normalize(velocity) * lookaheadDistance; if (terrain.CheckCollision(nextPos)) { // future intersection, try to avoid // brute force to find a resolution :/ PolarVector2 solver = new PolarVector2(); solver.Cartesian = nextPos - position; float startAngle = solver.angle; // search left and then right alternatley until we find a resolution // to the collision - we can only check if a single pixel is colliding, // we don't know the actual areas of bounds int limit = (int)Math.Ceiling(Math.PI / CRAPPY_COLLISION_SEARCH_RESOLUTION); for (int count = 0, alternator = 0; count <= limit; alternator = ++alternator % 2) { solver.angle = startAngle; float delta = CRAPPY_COLLISION_SEARCH_RESOLUTION * count; if (alternator == 1) { // search backwards around the circle solver.angle = solver.angle + -startAngle; ++count; } // see if we don't have a collision if (!terrain.CheckCollision(position + solver.Cartesian)) { // no collision return(seek(solver.Cartesian)); } } // failed to find a resolution, not good Debug.WriteLine(String.Format("Failed to resolve collision at: {0}, lookahead: {1}", position, lookaheadDistance)); Debug.Assert(false); } Debug.WriteLine(String.Format("No collision at: {0}", position)); return(Vector2.Zero); }
public Vector2 wander(float deviation, float distance, float maxAngleDelta) { lastWanderAngle += (float)(Engine.RND.NextDouble() * (maxAngleDelta * 2)) - maxAngleDelta; Vector2 rndPoint = new PolarVector2(deviation, lastWanderAngle).Cartesian; Vector2 offset = new PolarVector2(distance, Angle).Cartesian; Vector2 target = (rndPoint + offset); target.Normalize(); target *= distance; return(seek(position + target)); }