Esempio n. 1
0
        private void FindNearestNode(ComponentAI ai)
        {
            Vector3 distance;
            Vector3 shortestDistance = new Vector3(0, 0, 0);
            Node    closestNode      = null;
            bool    distanceSet      = false;

            foreach (Node node in map)
            {
                distance = ai.CurrentPosition - node.Location;

                if (distanceSet)
                {
                    if (distance.Length < shortestDistance.Length)
                    {
                        shortestDistance = distance;
                        closestNode      = node;
                    }
                }
                else
                {
                    distanceSet      = true;
                    shortestDistance = distance;
                    closestNode      = node;
                }
            }

            ai.CurrentNode         = new Vector2(closestNode.mapX, closestNode.mapY);
            ai.CurrentNodeLocation = closestNode.Location;
        }
Esempio n. 2
0
        /// <summary>
        /// Checks if the player is in the FOV of the drone
        /// </summary>
        /// <param name="ai"> the ai component of this entity </param>
        /// <param name="transform"> the transform component of this entity </param>
        /// <returns> true if the player is in the drones FOV </returns>
        private bool PlayerInFOV(ComponentAI ai, ComponentTransform transform)
        {
            //Finds the direction from the drone to the player
            Vector3 direction = (player.GetTransform().Translation - transform.Translation).Normalized();
            //Finds the angle between the target direction and the agent forward vector
            float angle = (float)(Math.Atan2(direction.X, direction.Z) - Math.Atan2(transform.Forward.X, transform.Forward.Z));

            //if the angle is over 180 in either direction then invert it to be a smaller angle in the opposite direction
            if (angle > Math.PI)
            {
                angle -= (float)(2 * Math.PI);
            }
            if (angle < -Math.PI)
            {
                angle += (float)(2 * Math.PI);
            }

            angle = MathHelper.RadiansToDegrees(angle);

            //if the player is in sight return true
            if (angle < ai.FOV && angle > -angle)
            {
                //Console.WriteLine("player spotted");
                return(true);
            }
            return(false);
        }
Esempio n. 3
0
        private bool SearchForPath(ComponentAI ai, Node currentNode)
        {
            //Gets list of passable neighbours and then sorts them by the estimated distance traveled if taking this node on the path (F) and sets current node to closed
            List <Node> passableNeighbours = GetPassableNeighbours(ai, currentNode);

            passableNeighbours.Sort((node1, node2) => node1.F.CompareTo(node2.F));
            currentNode.State = NodeState.Closed;

            //Recursively searches through each neighbour until the shortest path is found if a valid path is available
            foreach (Node passableNeighbour in passableNeighbours)
            {
                if (passableNeighbour.Location == ai.TargetNodeLocation)
                {
                    return(true);
                }
                else
                {
                    if (SearchForPath(ai, passableNeighbour))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Esempio n. 4
0
        private void SetNextNode(ComponentAI ai)
        {
            //Updates current node location then finds next node in the path and sets it as the next node
            ai.CurrentNodeLocation = ai.NextNodeLocation;

            if (ai.Path.Count() != 0)
            {
                ai.NextNode         = ai.Path[ai.PathNodesTraversed];
                ai.NextNodeLocation = map[(int)ai.Path[ai.PathNodesTraversed].X, (int)ai.Path[ai.PathNodesTraversed].Y].Location;
            }
            ai.NextSet = true;
        }
Esempio n. 5
0
        public void Motion(ComponentPosition pPos, ComponentVelocity pVel, ComponentAI pAI, string name)
        {
            // Updates the target with the most recent player position
            if (targetIsPlayer)
            {
                pAI.Target = mCamera.Position;
            }

            // Checks if the AI has found its target and skips search code for efficency
            if (RoundVectorPosition(pPos.Position).Xz == pAI.Target.Xz)
            {
                return;
            }

            // Checks if the AI's target is within map boundaries
            if (!(pAI.Target.X < (mWidth / 2) && !(pAI.Target.X > (mWidth / 2)) && pAI.Target.Z < (mHeight / 2) && !(pAI.Target.Z > (mHeight / 2))))
            {
                return;
            }

            // Makes sure target is in a traversable area
            if (!Traversable[(int)pAI.Target.Z + (mHeight / 2), (int)pAI.Target.X + (mWidth / 2)])
            {
                return;
            }

            if (pAI.Path.Length > 0 && pAI.ogTarget == pAI.Target)
            {
                // Path following
                Vector3 direction = pAI.Path[0] - pPos.Position;
                pPos.Position += direction * pVel.Veclotiy * deltaTime;
            }
            else
            {
                // Updates path finding
                pAI.ogTarget = pAI.Target;
                pAI.Path     = ASPath(RoundVectorPosition(pPos.Position), RoundVectorPosition(pAI.Target));
                // Path following
                if (pAI.Path.Length <= 0)
                {
                    // Path finding failed
                    return;
                }
                Vector3 direction = pAI.Path[0] - pPos.Position;
                pPos.Position += direction * pVel.Veclotiy * deltaTime;
            }
            // Check to see if AI has hit closest point in path and removes it if true so it can follow the next point
            if (RoundVectorPosition(pPos.Position) == pAI.Path[0])
            {
                pAI.Path = pAI.Path.Skip(1).ToArray();
            }
        }
Esempio n. 6
0
 public ComponentAI GetComponentAI()
 {
     //Checks if entity has an AI component
     if ((mask & ComponentTypes.COMPONENT_AI) == ComponentTypes.COMPONENT_AI)
     {
         //Gets AiComponent from entity
         ComponentAI aiComponent = (ComponentAI)componentList.Find(delegate(IComponent e)
         {
             return(e.ComponentType == ComponentTypes.COMPONENT_AI);
         });
         return(aiComponent);
     }
     return(null);
 }
Esempio n. 7
0
        public void OnAction(Entity entity)
        {
            if (entity.Name == "Player")
            {
                //Delete(entity);
            }

            if ((entity.Mask & MASK) == MASK)
            {
                List <IComponent> components = entity.Components;

                IComponent healthComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_HEALTH);
                });

                IComponent ammoComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_AMMO);
                });

                ComponentAI aiComponent = (ComponentAI)components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_AI);
                });
                AIStates state = aiComponent.CurrentState;


                IComponent pickupComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_PICK_UP);
                });

                IComponent aliveComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_ALIVE);
                });

                PowerUp((ComponentHealth)healthComponent, (ComponentAmmo)ammoComponent, (ComponentPickUp)pickupComponent, (ComponentAlive)(aliveComponent));


                if (pickupComponent == null && aliveComponent == null)
                {
                    Delete(entity);
                }
            }
        }
Esempio n. 8
0
        private List <Node> GetPassableNeighbours(ComponentAI ai, Node currentNode)
        {
            List <Node> passableNeighbours = new List <Node>();

            //Gets all neighbouring nodes of current node
            List <Node> neighbours = GetNeighbours(ai, currentNode);

            //Gets all walkable nodes in the neighbouring nodes that are more efficient nodes to use in the path than the currently chosen node
            foreach (Node neighbour in neighbours)
            {
                //Ignores closed nodes
                if (neighbour.State == NodeState.Closed)
                {
                    continue;
                }

                //Ignores unpassable nodes
                if (!neighbour.Passable)
                {
                    continue;
                }

                //If node has already been tested, tests to see if traversing the neighbouring node will be more efficient from this node than its parents node, then adds it to passable neighbours if it is
                if (neighbour.State == NodeState.Open)
                {
                    float gDistance     = new Vector3(neighbour.Location - neighbour.ParentNode.Location).Length;
                    float tempGDistance = currentNode.G + gDistance;
                    if (tempGDistance < neighbour.G)
                    {
                        neighbour.ParentNode = currentNode;
                        passableNeighbours.Add(neighbour);
                    }
                }
                //If node is currently untested, adds it to the passable neighbours list and sets it to Open State
                else
                {
                    neighbour.ParentNode = currentNode;
                    neighbour.State      = NodeState.Open;
                    passableNeighbours.Add(neighbour);
                }
            }
            return(passableNeighbours);
        }
Esempio n. 9
0
 /// <summary>
 /// Method to organise the ghost AI target points
 /// </summary>
 private void ManageGhostTargets()
 {
     // For every ghost in the system AI update its target
     for (int i = 0; i < NumberOfGhost; i++)
     {
         // Gets access to the AI componet and position component to update their values for each AI
         ComponentAI       Ai  = (ComponentAI)entityManager.FindEntityWithMask(ComponentTypes.COMPONENT_AI)[i].FindComponent(ComponentTypes.COMPONENT_AI);
         ComponentPosition Pos = (ComponentPosition)entityManager.FindEntityWithMask(ComponentTypes.COMPONENT_POSITION)[i].FindComponent(ComponentTypes.COMPONENT_POSITION);
         // If the player is powered up the the target should be the ghost start (makes them run away from the player)
         if (isPowerUp)
         {
             Ai.Target = StartPosition_Ghost;
         }
         // If the player is not powered up then the target is the player (the ghosts be hungery)
         else
         {
             Ai.Target = RoundVector(sceneManager.camera.Position);
         }
     }
 }
Esempio n. 10
0
        private void SetRandomPath(ComponentAI ai)
        {
            Node currentNode = map[(int)ai.CurrentNode.X, (int)ai.CurrentNode.Y];

            ai.Path.Clear();

            //Calculates total direct distance between nodes and target node
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < columns; j++)
                {
                    if (i != ai.CurrentNode.X && j != ai.CurrentNode.Y)
                    {
                        map[i, j].H = new Vector3(map[i, j].Location - ai.TargetNodeLocation).Length;
                    }
                    map[i, j].ParentNode = null;
                    map[i, j].State      = NodeState.Untested;
                }
            }

            //Returns true if a valid path to the target node can be found
            bool pathFound = SearchForPath(ai, currentNode);

            //If path is found, back tracks through the nodes in the path using the parent nodes to retrieve the complete path and then stores in a list from starting node to target node
            if (pathFound)
            {
                Node node = map[(int)ai.TargetNode.X, (int)ai.TargetNode.Y];
                while (node.ParentNode != null)
                {
                    ai.Path.Add(new Vector2(node.mapX, node.mapY));
                    node = node.ParentNode;
                }
                ai.Path.Reverse();
            }

            //Prints out path in console for debugging purposes
            foreach (Vector2 node in ai.Path)
            {
                //Console.WriteLine(node.X + ", " + node.Y);
            }
        }
        public void MoveToNextNode(ComponentAI ai)
        {
            List <Node> PossiblePaths = new List <Node>();

            foreach (var node in ai.TargetNode.Neighbours)
            {
                if (node == null)
                {
                    continue;
                }

                if (node.Walkable && node != ai.CurrentNode)
                {
                    PossiblePaths.Add(node);
                }
            }

            var newNode = PossiblePaths[AIManager.Instance.AIRandom.Next(0, PossiblePaths.Count)];

            ai.ToNextNode(newNode);
        }
Esempio n. 12
0
        public void OnAction(Entity entity)
        {
            if ((entity.Mask & MASK) == MASK)
            {
                List <IComponent> components = entity.Components;

                IComponent positionComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_POSITION);
                });

                ComponentAI aiComponent = (ComponentAI)components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_AI);
                });
                AIStates state = aiComponent.CurrentState;

                IComponent velocityComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_VELOCITY);
                });


                ComponentRotation rotationComponent = (ComponentRotation)components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_ROTATION);
                });
                Vector2 currentRotation = rotationComponent.Rotation.Xz;

                if (MyGame.NewCameraPosition != new Vector2(0, 0))
                {
                    PathFinding((ComponentPosition)positionComponent);
                }
                if (path.Count > 0)
                {
                    FollowPath((ComponentVelocity)velocityComponent, (ComponentPosition)positionComponent);
                }
                PlayerDetection((ComponentPosition)positionComponent, (ComponentVelocity)velocityComponent, state);
            }
        }
Esempio n. 13
0
        private List <Node> GetNeighbours(ComponentAI ai, Node currentNode)
        {
            List <Node> neighbours = new List <Node>();

            //Top
            neighbours.Add(map[(int)currentNode.mapX, (int)currentNode.mapY + 1]);
            //Bottom
            neighbours.Add(map[(int)currentNode.mapX, (int)currentNode.mapY - 1]);
            //Right
            neighbours.Add(map[(int)currentNode.mapX + 1, (int)currentNode.mapY]);
            //Left
            neighbours.Add(map[(int)currentNode.mapX - 1, (int)currentNode.mapY]);
            //Top Right
            //neighbours.Add(map[(int)currentNode.mapX + 1, (int)currentNode.mapY + 1]);
            //Bottom Right
            //neighbours.Add(map[(int)currentNode.mapX + 1, (int)currentNode.mapY - 1]);
            //Top Left
            //neighbours.Add(map[(int)currentNode.mapX - 1, (int)currentNode.mapY + 1]);
            //Bottom Left
            //neighbours.Add(map[(int)currentNode.mapX - 1, (int)currentNode.mapY - 1]);

            return(neighbours);
        }
Esempio n. 14
0
        private void SetTargetNode(ComponentAI ai)
        {
            bool targetSet = false;
            int  randomX   = 0;
            int  randomY   = 0;

            //Randomly chooses a target node that is passable on the map grid
            while (!targetSet)
            {
                randomX = rnd.Next(1, rows);
                randomY = rnd.Next(1, columns);

                //Ensures that the chosen target node is passable, then sets new target node
                if (map[randomX, randomY].Passable == true)
                {
                    ai.TargetNode         = new Vector2(randomX, randomY);
                    ai.TargetNodeLocation = map[randomX, randomY].Location;
                    targetSet             = true;
                    ai.TargetSet          = true;
                    ai.PathNodesTraversed = 0;
                }
            }
        }
        public void OnAction()
        {
            foreach (Entity entity in entityList)
            {
                List <IComponent> components = entity.Components;

                IComponent transformComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_TRANSFORM);
                });

                IComponent velocityComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_VELOCITY);
                });

                IComponent aiComponent = components.Find(delegate(IComponent component)
                {
                    return(component.ComponentType == ComponentTypes.COMPONENT_AI);
                });

                if (((ComponentTransform)transformComponent).SetTransform == false)
                {
                    UpdateTransform((ComponentTransform)transformComponent);
                    ((ComponentTransform)transformComponent).SetTransform = true;
                }

                #region AI movement
                //Checks if the entity has an AI component, then applies movement based on AI path
                if (aiComponent != null)
                {
                    ComponentAI        ai        = ((ComponentAI)aiComponent);
                    float              velocity  = ((ComponentVelocity)velocityComponent).Velocity;
                    ComponentTransform transform = ((ComponentTransform)transformComponent);
                    ai.CurrentPosition = transform.Translation;
                    Vector3 direction;
                    float   angle;

                    if (ai.Disabled != true)
                    {
                        if (ai.CanSeePlayer)
                        {
                            //Finds direction towards target
                            direction    = new Vector3(ai.PlayerPosition - transform.Translation).Normalized();
                            ai.TargetSet = false;
                            ai.NextSet   = false;
                        }
                        else
                        {
                            //Finds the direction towards the target node
                            direction = new Vector3(ai.NextNodeLocation - transform.Translation).Normalized();
                        }

                        //Finds the angle between the target direction and the agent forward vector
                        angle = (float)(Math.Atan2(direction.X, direction.Z) - Math.Atan2(transform.Forward.X, transform.Forward.Z));

                        //if the angle is over 180 in either direction then invert it to be a smaller angle in the opposite direction
                        if (angle > Math.PI)
                        {
                            angle -= (float)(2 * Math.PI);
                        }
                        if (angle < -Math.PI)
                        {
                            angle += (float)(2 * Math.PI);
                        }

                        //Rotates the agent a fraction of the angle found each frame and moves the agent forward
                        transform.Rotation    += new Vector3(0, angle / 5, 0);
                        transform.Translation += transform.Forward * velocity * sceneManager.dt;

                        if (!ai.CanSeePlayer)
                        {
                            //Checks if entity has reached the next node then sets current node to the next node causing the AI system to update to a new next node
                            if ((int)(transform.Translation.X + 0.4f) == ai.NextNodeLocation.X && transform.Translation.Y == ai.NextNodeLocation.Y && (int)(transform.Translation.Z + 0.4f) == ai.NextNodeLocation.Z)
                            {
                                ai.CurrentNode = ai.NextNode;
                            }

                            //Checks if entity has reached the target node then sets current node to the target node causing the AI system to update to a new target node
                            if ((int)(transform.Translation.X + 0.4f) == ai.TargetNodeLocation.X && (int)(transform.Translation.Y) == ai.TargetNodeLocation.Y && (int)(transform.Translation.Z + 0.4f) == ai.TargetNodeLocation.Z)
                            {
                                ai.CurrentNode = ai.TargetNode;
                            }
                        }
                    }
                }
                #endregion

                UpdateTransform((ComponentTransform)transformComponent);
            }
        }