public SteeringBehaviors(MovingEntity entity, MovingEntity enemy) { _entity = entity; rand = new Random(); _mDWanderRadius = 2.5f; m_dWanderDistance = 3f; m_vSteeringForce = new Vector2D(); m_dWanderJitter = 40f; m_dViewDistance = 40; m_dWeightSeparation = 5000; MinDetectionBoxLength = 20; m_dWeightObstacleAvoidance = 9000000; double rotation = VectorHelper.RandFloat() * (Math.PI * 2); m_vWanderTarget = new Vector2D(_mDWanderRadius * Math.Cos(rotation), _mDWanderRadius * Math.Sin(rotation)); m_pTargetAgent1 = enemy; AStarTargets = new List<Node>(); ExploreTargets = new Queue<Vector2D>(); ExploreTargets.Enqueue(new Vector2D(100,100)); //Left-Top ExploreTargets.Enqueue(new Vector2D(100, 500)); //Left-Bottom ExploreTargets.Enqueue(new Vector2D(800, 500)); //Mid-Bottom ExploreTargets.Enqueue(new Vector2D(800, 100)); //Mid-Top ExploreTargets.Enqueue(new Vector2D(1500, 100)); //Right-Top ExploreTargets.Enqueue(new Vector2D(1500, 500)); //Right-Bottom ExploreTargets.Enqueue(new Vector2D(800, 450)); //Mid-Mid ExploreTargets.Enqueue(new Vector2D(100, 450)); // Mid-Left ExploreTargets.Enqueue(new Vector2D(1500, 450)); // Mid-Right }
public AnimatedTexture(Vector2D Origin, float Rotation, float Scale, float Depth) { this.Origin = Origin; this.Rotation = Rotation; this.Scale = Scale; this.Depth = Depth; }
public void DrawFrame(SpriteBatch Batch, int Frame, Vector2D screenpos, int sourceY) { int FrameWidth = myTexture.Width / framecount; Rectangle sourcerect = new Rectangle(FrameWidth * Frame, sourceY, FrameWidth, myTexture.Height / 7); Batch.Draw(myTexture, screenpos.toVector2(), sourcerect, Color.White, Rotation, new Vector2((float)Origin.X / 2,(float)Origin.Y /2), Scale, SpriteEffects.None, Depth); }
public static Vector2D MaxLimit(Vector2D vector, float limit) { if (vector.Length() > limit) { var factor = vector.Length() / limit; vector = vector / factor; } return vector; }
public override void Update(float timeElapsed) { if (Pos.X > 1600) { Pos = new Vector2D(0, Pos.Y); } if (Pos.X < 0) { Pos = new Vector2D(1600, Pos.Y); } if (Pos.Y < 0) { Pos = new Vector2D(Pos.X, 900); } if (Pos.Y > 900) { Pos = new Vector2D(Pos.X, 0); } _personTexture.UpdateFrame(timeElapsed); }
public Citizen() { SteeringBehaviors = new SteeringBehaviors(this, enemy); _personTexture = new AnimatedTexture(new Vector2D(16,16), 0, 1, 0); Mass = 0.1f; double rotation = VectorHelper.RandFloat()*(Math.PI*2); Heading = new Vector2D((float)Math.Sin(rotation), (float)-Math.Cos(rotation)); MaxSpeed = 50f; MaxForce = 50f; Velocity = new Vector2D(0, 0); Side = Heading.Perp(); Target = new Vector2D(0,0); Bradius = 16; Brain = new Think(this); Brain.Activate(); Strength = 0; fm = new FuzzyModule(); Fuzzy_Desirability = fm.CreateFLV("Desirability"); FuzzySet Low_Desirability = Fuzzy_Desirability.AddLeftShoulderSet("Low", 0, 100, 200); FuzzySet Average_Desirability = Fuzzy_Desirability.AddTriangleSet("Average", 100, 200, 375); FuzzySet Very_Desirability = Fuzzy_Desirability.AddRightShoulderSet("Very", 200, 375, 500); Fuzzy_DistanceToTarget = fm.CreateFLV("Distance to Target"); FuzzySet TargetClose = Fuzzy_DistanceToTarget.AddLeftShoulderSet("TargetClose", 0, 300, 800); FuzzySet TargetMedium = Fuzzy_DistanceToTarget.AddTriangleSet("TargetMedium", 300, 800, 1300); FuzzySet TargetFar = Fuzzy_DistanceToTarget.AddRightShoulderSet("TargetFar", 800, 1300, 1600); Fuzzy_Strength = fm.CreateFLV("Strength"); FuzzySet Weak_Strength = Fuzzy_Strength.AddLeftShoulderSet("Weak", 0, 10000, 50000); FuzzySet Average_Strength = Fuzzy_Strength.AddTriangleSet("Average", 10000, 50000, 75000); FuzzySet Strong_Strength = Fuzzy_Strength.AddRightShoulderSet("Strong", 50000, 75000, 100000); fm.AddRule(new FuzzyAnd(Strong_Strength, TargetClose), Very_Desirability); fm.AddRule(new FuzzyAnd(Strong_Strength, TargetMedium), Average_Desirability); fm.AddRule(new FuzzyAnd(Strong_Strength, TargetFar), Low_Desirability); fm.AddRule(new FuzzyAnd(Weak_Strength, TargetClose), Low_Desirability); fm.AddRule(new FuzzyAnd(Weak_Strength, TargetMedium), Average_Desirability); fm.AddRule(new FuzzyAnd(Weak_Strength, TargetFar), Very_Desirability); fm.AddRule(new FuzzyAnd(Average_Strength, TargetMedium), Average_Desirability); fm.AddRule(new FuzzyAnd(Average_Strength, TargetClose), Average_Desirability); fm.AddRule(new FuzzyAnd(Average_Strength, TargetFar), Average_Desirability); }
//create a rotation matrix from a 2D vector public void Rotate(Vector2D fwd, Vector2D side) { Matrix mat = new Matrix(); mat._11 = fwd.X; mat._12 = fwd.Y; mat._13 = 0; mat._21 = side.X; mat._22 = side.Y; mat._23 = 0; mat._31 = 0; mat._32 = 0; mat._33 = 1; //and multiply MatrixMultiply(mat); }
//applies a 2D transformation matrix to a single Vector2D public void TransformVector2D(Vector2D vPoint) { double tempX = (m_Matrix._11 * vPoint.X) + (m_Matrix._21 * vPoint.Y) + (m_Matrix._31); double tempY = (m_Matrix._12 * vPoint.X) + (m_Matrix._22 * vPoint.Y) + (m_Matrix._32); vPoint.X = (float)tempX; vPoint.Y = (float)tempY; }
public void UpdateThug(Keys key) { const int speed = 5; Vector2D oldPos = thug.Pos; Vector2D tempHeading = new Vector2D(0, 0); if (key == Keys.Up) { thug.Pos = new Vector2D(thug.Pos.X, thug.Pos.Y - speed); tempHeading += thug.Pos - oldPos; } if (key == Keys.Down) { thug.Pos = new Vector2D(thug.Pos.X, thug.Pos.Y + speed); tempHeading += thug.Pos - oldPos; } if (key == Keys.Left) { thug.Pos = new Vector2D(thug.Pos.X - speed, thug.Pos.Y); tempHeading += thug.Pos - oldPos; } if (key == Keys.Right) { thug.Pos = new Vector2D(thug.Pos.X + speed, thug.Pos.Y); tempHeading += thug.Pos - oldPos; } thug.Heading = Vector2D.Vec2DNormalize(tempHeading); }
public int Sign(Vector2D v2) { if (y * v2.X > x * v2.Y) { return (int)Enum_Sign.anticlockwise; } else { return (int)Enum_Sign.clockwise; } }
public static bool IsNull(Vector2D v) { if ((object)v == null) return true; return false; }
public override void Update(float timeElapsed) { TimeEllapsed = timeElapsed; CalculateDistance(); Brain.Arbitrate(); Brain.Process(); if (Flee) SteeringBehaviors.FleeOn(); else SteeringBehaviors.FleeOff(); if (Wander) SteeringBehaviors.WanderOn(); else SteeringBehaviors.WanderOff(); if (Seek) SteeringBehaviors.SeekOn(); else SteeringBehaviors.SeekOff(); if (Explore) SteeringBehaviors.ExploreOn(); else SteeringBehaviors.ExploreOff(); if (AStar) SteeringBehaviors.AStarOn(); else SteeringBehaviors.AStarOff(); SteeringBehaviors.SetTarget(enemy.Pos); SteeringForce = SteeringBehaviors.Calculate(); Vector2D acceleration = SteeringForce / Mass; Velocity += acceleration * timeElapsed; Velocity.Truncate(MaxSpeed); Pos += Velocity * timeElapsed; if (Velocity.LengthSq() > 0.00000001) { Heading = Vector2D.Vec2DNormalize(Velocity); Side = Heading.Perp(); } if (Pos.X > 1600) { Pos = new Vector2D(0, Pos.Y); } if (Pos.X < 0) { Pos = new Vector2D(1600, Pos.Y); } if (Pos.Y < 0) { Pos = new Vector2D(Pos.X, 900); } if (Pos.Y > 900) { Pos = new Vector2D(Pos.X, 0);} _personTexture.UpdateFrame(TimeEllapsed); Strength++; }
public Thug() { _personTexture = new AnimatedTexture(new Vector2D(16,16), 0, 1, 0); Heading = new Vector2D(0,0); Bradius = 16; }
private Vector2D VectorToWorldSpace(Vector2D vec, Vector2D AgentHeading, Vector2D AgentSide) { //make a copy of the point Vector2D TransVec = new Vector2D(vec.X, vec.Y); ; //create a transformation matrix C2DMatrix matTransform = new C2DMatrix(); //rotate matTransform.Rotate(AgentHeading, AgentSide); //now transform the vertices matTransform.TransformVector2D(TransVec); return TransVec; }
//treats a window as a toroid public static Vector2D WrapAround(Vector2D pos, int MaxX, int MaxY) { Vector2D newPos = pos; if (pos.X > MaxX) { newPos.X = 0.0; } if (pos.X < 0) { newPos.X = (double)MaxX; } if (pos.Y < 0) { newPos.Y = (double)MaxY; } if (pos.Y > MaxY) { newPos.Y = 0.0; } return newPos; }
public static Vector2D Vec2DNormalize(Vector2D v) { Vector2D vec = new Vector2D(v.X, v.Y); double vector_length = vec.Length(); if (vector_length > double.Epsilon) { vec.X /= vector_length; vec.Y /= vector_length; } return vec; }
public static double Vec2DDistanceSq(Vector2D v1, Vector2D v2) { double ySeparation = v2.Y - v1.y; double xSeparation = v2.X - v1.x; return ySeparation * ySeparation + xSeparation * xSeparation; }
public static double Vec2DDistance(Vector2D v1, Vector2D v2) { double ySeparation = v2.Y - v1.y; double xSeparation = v2.X - v1.x; return Math.Sqrt(ySeparation * ySeparation + xSeparation * xSeparation); }
//------------------------ ProjectedPerp --------------------------------- // // Returns a vector perpendicular to the given direction, projected out // by radius amount from the origin. The new perpendicular direction // points to the left if swapHand is true, and to the right otherwise. //------------------------------------------------------------------------ public static Vector2D ProjectedPerp(Vector2D origin, Vector2D DirNormal, double radius, bool swapHand) { Vector2D dir; Vector2D targetLoc = new Vector2D(); if (swapHand) { dir = new Vector2D(DirNormal.Y, -DirNormal.X); } else { dir = new Vector2D(-DirNormal.Y, DirNormal.X); } targetLoc.X = origin.X + (radius * dir.X); targetLoc.Y = origin.Y + (radius * dir.Y); return targetLoc; }
//returns true if the point p is not inside the region defined by top_left and bot_rgt public static bool NotInsideRegion(Vector2D p, Vector2D top_left, Vector2D bot_rgt) { return (p.X < top_left.X) || (p.X > bot_rgt.X) || (p.Y < top_left.Y) || (p.Y > bot_rgt.Y); }
//------------------ isSecondInFOVOfFirst ------------------------------------- // // returns true if the target position is in the field of view of the entity // positioned at posFirst facing in facingFirst //----------------------------------------------------------------------------- public static bool isSecondInFOVOfFirst(Vector2D posFirst, Vector2D facingFirst, Vector2D posSecond, double fov) { Vector2D toTarget = Vec2DNormalize(posSecond - posFirst); return facingFirst.Dot(toTarget) >= Math.Cos(fov / 2.0); }
private Vector2D Wander() { //this behavior is dependent on the update rate, so this line must //be included when using time independent framerate. var jitterThisTimeSlice = m_dWanderJitter * _entity.TimeEllapsed; if (jitterThisTimeSlice <= 0) jitterThisTimeSlice = 1; //first, add a small random vector to the target's position m_vWanderTarget += new Vector2D((float)(VectorHelper.RandomClamped() * jitterThisTimeSlice), (float)(VectorHelper.RandomClamped() * jitterThisTimeSlice)); //reproject this new vector back on to a unit circle m_vWanderTarget.Normalize(); //increase the length of the vector to the same as the radius //of the wander circle m_vWanderTarget *= (float)_mDWanderRadius; //move the target into a position WanderDist in front of the agent Vector2D target = m_vWanderTarget + new Vector2D(m_dWanderDistance, 0); //project the target into world space _entity.Target = PointToWorldSpace(target, _entity.Heading, _entity.Side, _entity.Pos); //and steer towards it return _entity.Target - _entity.Pos; }
public static Vector2D GetPerpVector(Vector2D vec) { return new Vector2D(-vec.Y, vec.X); }
//------------------------------ DistanceSq ------------------------------ // // calculates the euclidean distance squared between two vectors //------------------------------------------------------------------------ public double DistanceSq(Vector2D v2) { double ySeparation = v2.Y - y; double xSeparation = v2.X - x; return ySeparation * ySeparation + xSeparation * xSeparation; }
public static Vector2D ToLimit(Vector2D vector, float limit) { var factor = vector.Length() / limit; vector = vector / factor; return vector; }
//------------------------- Vec2DDot ------------------------------------- // // calculates the dot product //------------------------------------------------------------------------ public double Dot(Vector2D v2) { return x * v2.X + y * v2.y; }
private Vector2D Separation(List<MovingEntity> neighbors) { Vector2D SteeringForce = new Vector2D(0.0, 0.0); foreach (MovingEntity neighbor in neighbors) { //make sure this agent isn't included in the calculations and that //the agent being examined is close enough. //***also make sure it doesn't include the evade target *** if ((neighbor != _entity) && neighbor.IsTagged && (neighbor != m_pTargetAgent1)) { Vector2D ToAgent = (_entity.Pos - neighbor.Pos); //scale the force inversely proportional to the agents distance from its neighbor. SteeringForce += Vector2D.Vec2DNormalize(ToAgent) / ToAgent.Length(); } } return SteeringForce; }
//--------------------------- Reflect ------------------------------------ // // given a normalized vector this method reflects the vector it // is operating upon. (like the path of a ball bouncing off a wall) //------------------------------------------------------------------------ public void Reflect(Vector2D norm) { //this += 2.0 * this.Dot(norm) * norm.GetReverse(); Vector2D vecTemp = norm.GetReverse() * this.Dot(norm) * 2.0; this.X = vecTemp.X; this.Y = vecTemp.Y; }
//------------------------------ Distance -------------------------------- // // calculates the euclidean distance between two vectors //------------------------------------------------------------------------ public double Distance(Vector2D v2) { double ySeparation = v2.Y - y; double xSeparation = v2.X - x; return Math.Sqrt(ySeparation * ySeparation + xSeparation * xSeparation); }
public static bool InsideRegion(Vector2D p, int left, int top, int right, int bottom) { return !((p.X < left) || (p.X > right) || (p.Y < top) || (p.Y > bottom)); }