Beispiel #1
0
        public override void UpdateEntity(int entity)
        {
            CBoid        boid        = (CBoid)boids[entity];
            CPosition    position    = (CPosition)positions[entity];
            CDimension   dimension   = (CDimension)dimensions[entity];
            CTransform   transform   = (CTransform)transforms[entity];
            CPhysicsBody physicsBody = (CPhysicsBody)physicsBodies[entity];

            Vector2 myCenter = new Vector2(position.X + dimension.Width / 2, position.Y + dimension.Height / 2);

            Vector2 cumulativeSeperation = Vector2.Zero;
            int     totalSeperation      = 0;

            Vector2 cumulativeAlignment = Vector2.Zero;
            int     totalAlignment      = 0;

            Vector2 cumulativeCohesion = Vector2.Zero;
            int     totalCohesion      = 0;

            float        distance;
            CPosition    theirPosition;
            CDimension   theirDimension;
            CPhysicsBody theirPhysicsBody;
            Vector2      force;
            Vector2      theirCenter;

            List <int> queryResult = binPartitioner.Query(new Morro.Core.Rectangle(position.X - boid.ViewRadius, position.Y - boid.ViewRadius, dimension.Width + boid.ViewRadius * 2, dimension.Height + boid.ViewRadius * 2));

            for (int i = 0; i < queryResult.Count; i++)
            {
                if (queryResult[i] == entity)
                {
                    continue;
                }

                theirPosition    = (CPosition)positions[queryResult[i]];
                theirDimension   = (CDimension)dimensions[queryResult[i]];
                theirPhysicsBody = (CPhysicsBody)physicsBodies[queryResult[i]];

                theirCenter = new Vector2(theirPosition.X + theirDimension.Width / 2, theirPosition.Y + theirDimension.Height / 2);

                distance = Vector2.Distance(myCenter, theirCenter);

                if (distance > 0)
                {
                    if (distance < boid.ViewRadius)
                    {
                        cumulativeCohesion += theirCenter;
                        totalCohesion++;

                        cumulativeAlignment += theirPhysicsBody.Velocity;
                        totalAlignment++;
                    }

                    if (distance < theirDimension.Width * 2)
                    {
                        force  = myCenter - theirCenter;
                        force /= distance * distance;
                        cumulativeSeperation += force;
                        totalSeperation++;
                    }

                    if (distance < 64 && theirDimension.Width > 2)
                    {
                        force  = myCenter - theirCenter;
                        force /= distance * distance;
                        cumulativeSeperation += force * 4;
                        totalSeperation++;
                    }
                }
            }

            distance = Vector2.Distance(Morro.Input.Mouse.SceneLocation, myCenter);

            if (distance > 0 && distance < 32)
            {
                force  = myCenter - Morro.Input.Mouse.SceneLocation;
                force /= distance * distance;
                cumulativeSeperation += force;
                totalSeperation++;
            }

            Vector2 seperation = CalculateSeperation();
            Vector2 alignment  = CalculateAlignment();
            Vector2 cohesion   = CalculateCohesion();

            Vector2 totalForce = seperation + alignment + cohesion;

            physicsBody.Velocity += totalForce;
            transform.Rotation    = -(float)Math.Atan2(physicsBody.Velocity.Y, physicsBody.Velocity.X);

            Vector2 CalculateSeperation()
            {
                if (totalSeperation <= 0)
                {
                    return(Vector2.Zero);
                }

                cumulativeSeperation /= totalSeperation;
                cumulativeSeperation.SetMagnitude(boid.MoveSpeed);
                Vector2 result = cumulativeSeperation - physicsBody.Velocity;

                result.Limit(boid.MaxForce);

                return(result * seperationIntensity);
            }

            Vector2 CalculateAlignment()
            {
                if (totalAlignment <= 0)
                {
                    return(Vector2.Zero);
                }

                cumulativeAlignment /= totalAlignment;
                cumulativeAlignment.SetMagnitude(boid.MoveSpeed);
                Vector2 result = cumulativeAlignment - physicsBody.Velocity;

                result.Limit(boid.MaxForce);

                return(result * alignmentIntensity);
            }

            Vector2 CalculateCohesion()
            {
                if (totalCohesion <= 0)
                {
                    return(Vector2.Zero);
                }

                cumulativeCohesion /= totalCohesion;
                cumulativeCohesion -= myCenter;
                cumulativeCohesion.SetMagnitude(boid.MoveSpeed);
                Vector2 result = cumulativeCohesion - physicsBody.Velocity;

                result.Limit(boid.MaxForce);

                return(result * cohesionIntensity);
            }
        }
Beispiel #2
0
 public void SetPrevious(CBoid _previous)
 {
     previous = _previous;
 }
Beispiel #3
0
 public void LinkOut()
 {
     next     = null;
     previous = null;
 }
Beispiel #4
0
 public void SetNext(CBoid _next)
 {
     next = _next;
 }
Beispiel #5
0
 public abstract Vector3 Cruising(CBoid _cBoid);