Example #1
0
        /// <summary>
        /// Handler for scaring animals that are close to a hit
        /// </summary>
        /// <param name="obj">ID of damage receiver</param>
        private void handleHit(object obj)
        {
            var key = obj as int?;

            if (!key.HasValue)
            {
                return;
            }
            var scene = Game1.Inst.Scene;

            if (!scene.EntityHasComponent <CTransform>(key.Value))
            {
                return;
            }
            var hitLocation = ((CTransform)scene.GetComponentFromEntity <CTransform>(key.Value)).Position;

            foreach (var aiEntity in scene.GetComponents <CAI>())
            {
                if (!scene.EntityHasComponent <CTransform>(aiEntity.Key))
                {
                    continue;
                }
                var aiLocation = ((CTransform)(scene.GetComponentFromEntity <CTransform>(aiEntity.Key))).Position;
                if (PositionalUtil.Distance(hitLocation, aiLocation) <= ScaryDistance)
                {
                    var aiComponent = (CAI)aiEntity.Value;
                    aiComponent.State         = new SEvade(aiEntity.Key);
                    aiComponent.StateLockTime = ScaryTime;
                }
            }
        }
Example #2
0
        private Vector3 Separation(Vector3 position, CFlock flock)
        {
            // Separation
            // Method checks for nearby boids and steers away
            Vector3 steer = Vector3.Zero;
            int     count = 0;

            // For every boid in the system, check if it's too close
            foreach (var other in flock.Members)
            {
                var   otherTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(other);
                float d = PositionalUtil.Distance(position, otherTransform.Position);
                // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
                if ((d > 0) && (d < flock.SeparationDistance))
                {
                    // Calculate vector pointing away from neighbor
                    Vector3 diff = Vector3.Normalize(position - otherTransform.Position);

                    //Vector3 diff = Vector3.Subtract(position, otherTransform.Position);
                    //diff.Normalize();
                    diff  /= d;       // Weight by distance (makes closer neighbors more important to steer away from)
                    steer += diff;
                    count++;          // Keep track of how many
                }
            }
            // Average -- divide by how many
            if (count > 0)
            {
                steer /= count;
            }

            /*
             * // As long as the vector is greater than 0
             * if (steer.X > 0 || steer.Y > 0 || steer.Z > 0) {
             *  // First two lines of code below could be condensed with new PVector setMag() method
             *  // Not using this method until Processing.js catches up
             *  // steer.setMag(maxspeed);
             *
             *  // Implement Reynolds: Steering = Desired - Velocity
             *  steer.Normalize();
             *  steer *= (maxspeed);
             *  steer.sub(velocity);
             *  steer.limit(maxforce);
             * }*/
            //steer.Normalize();

            return(steer);
        }
Example #3
0
        public override void Update(float t, float dt)
        {
            foreach (var flockKeyPair in Game1.Inst.Scene.GetComponents <CFlock>())
            {
                var flock = (CFlock)flockKeyPair.Value;

                // Calculate flock centroid and avg velocity (used in some states)
                Vector3 theCenter   = Vector3.Zero;
                Vector3 theVelocity = Vector3.Zero;
                foreach (var npcKey in flock.Members)
                {
                    var npcTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(npcKey);
                    var npcBody      = (CBody)Game1.Inst.Scene.GetComponentFromEntity <CBody>(npcKey);
                    theCenter   = theCenter + npcTransform.Position;
                    theVelocity = theVelocity + npcBody.Velocity;
                }
                var flockSize = new Vector3(flock.Members.Count);
                flock.Centroid    = theCenter / flockSize;
                flock.AvgVelocity = theVelocity / flockSize;

                foreach (var npcKey in flock.Members)
                {
                    var npcComponent = (CAI)Game1.Inst.Scene.GetComponentFromEntity <CAI>(npcKey);
                    var npcTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(npcKey);
                    if (npcComponent.State == null)
                    {
                        npcComponent.State = new SIdle(npcKey);
                    }

                    if (npcComponent.StateLockTime <= 0)
                    {
                        // find closest enemy
                        var closestEnemyDistance = float.MaxValue;
                        var closestEnemyId       = -1;
                        foreach (var player in Game1.Inst.Scene.GetComponents <CPlayer>())
                        {
                            if (!Game1.Inst.Scene.EntityHasComponent <CBody>(player.Key))
                            {
                                continue;
                            }

                            var playerTransform = (CTransform)Game1.Inst.Scene.GetComponentFromEntity <CTransform>(player.Key);

                            var distance = PositionalUtil.Distance(playerTransform.Position, npcTransform.Position);

                            if (closestEnemyDistance > distance)
                            {
                                closestEnemyDistance = distance;
                                closestEnemyId       = player.Key;
                            }
                        }
                        if (closestEnemyId == -1)
                        {
                            return;
                        }
                        var enemyBody = (CBody)Game1.Inst.Scene.GetComponentFromEntity <CBody>(closestEnemyId);

                        // Save fuzzy values instead of recalculating on every rule
                        var closeToEnemy   = CloseToEnemy(closestEnemyDistance);
                        var fastEnemySpeed = FastSpeed(enemyBody.Velocity);
                        var mediumToEnemy  = MediumToEnemy(closestEnemyDistance);

                        // Test rules and set state accordingly
                        if ((closeToEnemy & fastEnemySpeed).IsTrue())
                        {
                            if (npcComponent.State.GetType() != typeof(SEvade))
                            {
                                npcComponent.State         = new SEvade(npcKey);
                                npcComponent.StateLockTime = ScaryTime;
                            }
                        }
                        else if ((FuzzyUtil.Very(closeToEnemy) & !fastEnemySpeed).IsTrue())
                        {
                            if (npcComponent.State.GetType() != typeof(SAware))
                            {
                                npcComponent.State = new SAware(npcKey);
                            }
                        }
                        else if (npcComponent.State.GetType() != typeof(SIdle))
                        {
                            npcComponent.State = new SIdle(npcKey);
                        }
                    }
                    // Act upon state
                    npcComponent.State.Handle(t, dt);
                    npcComponent.StateLockTime = Math.Max(npcComponent.StateLockTime - dt, 0);
                }
            }
        }