Right now we only have one ghost that moves around the maze in a pseudo-random fashion. This if fine, but we actually want to give the ghost some sort of intelligence. We actually won't be giving the ghost intelligence, just the appearance of something that is intelligent. The main secret behind this is that we just need to give the ghost a goal to reach. When you give the ghosts or any other entity a goal to reach, then the choices they make to determine which way to go when reaching a node will be based on which direction gets them closer to the goal. The goal that we want to give the ghost is just an (x, y) Vector. The ghost's main goal in life is to reach that coordinate, even if that coordinate is not reachable. That's an important thing to remember, the goal does not have to be reachable. So, let's give our ghost a goal and see how this works.
We need to add a goal vector for the ghost. Right now we'll just set the goal to be the origin of the screen, which is the top left corner of the screen. This position is unreachable to the ghost, but that shouldn't matter.
So the whole point of having a goal is to reach that goal, or at least try to. What this method does is take a list of directions, we'll assume they are already valid directions, and for each of the directions in the list it will calculate the distance from the entity to the goal. Then it returns the direction with the smallest distance. That direction will be chosen instead of choosing a random direction. We find the best direction by calculating the line of sight distance from each direction and just choosing the direction with the shortest line of sight distance. Because we're in a maze, however, the shortest line of sight won't always be the shortest distance the ghost must travel, but it's good enough for now and most importantly it's really fast to figure out. We don't need any fancy A* algorithms here, you can if you want to though. Extra credit if you do!
What you should see after you implement these changes is that the ghost will be moving around in a circle in the upper left corner. This is because the ghost is basically trying to reach the screen's origin which is the upper left corner of the screen, but can't because of the movement restrictions we've placed on it. Remember that it can't ever STOP during the game, so it has to choose a target every time it reaches a node, even if that target takes it further from the goal. But if it is able to choose a target that takes it closer to the goal, it will. What's nice about this is that we can give it any position on or off the screen and it will traverse the maze on its own trying to get to that position. This is the heart behind the ghosts AI. Try giving the ghost a different initial position rather than the first node. The ghost will maneuver around the maze until it reaches the top left corner, at which point it will just move around in a circle forever, or until we exit the game loop. Next we need to understand something called Modes. This will give our ghosts AI more sophistication.
So for any entity that needs to reach a goal, they need to call this method instead of the randomDirection method. I don't want to have to rewrite the update method for the ghosts just because they use a different method for getting their next direction. So in the entity class we'll create a new variable that will just hold the method that we use to get the direction for the entity. By default, this will be the randomDirection method. We can set this variable to other methods, but all of the methods we use have to have a single input.
Now we'll just tell the ghost to use the new method rather than the randomDirections method.
Once all is said and done you'll see the ghost circle the top left corner of the screen continuously.