开发者

XNA AI: Managing Enemies on Screen

I have two classes, Human and Monster.

both have a Property called MoveBehavior

Human has HumanMoveBehavior, and Monster has MonsterMoveBehavior

I want the HumanMoveBehavior to move AWAY from Monsters, and MonsterMoveBehavior to move TOWARD Humans.

The problem I'm having is whe开发者_开发百科re should I put my code to move?

In the Human/Monster class?

Using this approach, I had a Move() Method, which takes a List of all entities in game, decides whether it's a Monster or Human using a method called GetListOfOpponents(List allsprites) and then runs GetNearestOpponent(List opponents);

But this looks really messy.

Should I have a SpriteController that decides where the Sprites move? I'm unsure where I need to put this code :(

Thanks!


You could think of a AIManager that just says:

foreach(GameObject go in m_myObjects) // m_myObjects is a list of all objects that require updating
{
    go.Update(); // standard GameObject function
}

After that, each class should take care of its own piece of code. So updating works in the class itself.

So Human says:

// just a class which is a gameObject and also has moving behaviour
// do the same with monster
public class Human : GameObject, IMoveBehaviour
{
    public override Update()
    {
        GoMove();
    }

    public void GoMove()
    {
        // human specific logic here
    }
}

// This interface describes that some movement 
// will happen with the implementing class
public interface IMoveBehaviour
{
    void GoMove();
}

With using an interface, you can make the specific language part of the class and you don't have need to ALSO create some class that will handle that for you. Of course it is possible. But in real life, the human/monster is the one that is moving, not some object he is carrying.

UPDATE

Answer to the comment. Because there is an AIManager, or even a complete GameObjectManager would be nice to maintain all GameObjects, you could ask the AIManager for the placed where you could not go.

Because pathfinding is most of the time done by use of some navigation mesh or a specified grid, the GameObjectManager can return the specific Grid with all navigable points on it. You should for certain not define all positions in every monster. Because most of the time, the monster does not exactly know where everyone is (in real life). So knowing where not to go is indeed good, but knowing where everyone is, will give your AI too much advantage as well.

So think of returning a grid with the points where to go and where not to, instead of maintaining such things inside the monster/human. Always check where you should leave what, by thinking about what would be the thing in real life.


The way Valve handled this for entities in Half Life 2, is one of the better ways, I think. Instead of giving each AI its own separate Move methods and calling those, it simply called the Think() method and let the entity decide what it needed to do.

I'd go with what Marnix says and implement an AIManager that loops through each active AI in the game world, calling the Think() method of each. I would not recommended interfacing your Human class with an "IMoveBehavior" simply because it would be better to abstract that into a "WorldEntity" abstract class.

You might have invisible entities that control things like autosaves, triggers, lighting, etc, but some will have a position in the world. These are the ones who will have a vector identifying their position. Have the AI's Think() method call its own move() method, but keep it private. The only one who needs to think about moving is the AI itself.

If you want to encourage the AI to move outside of the Think) method, I would suggest some kind of imperative, such as a Goal-Oriented Action Planning (GOAP) system. Jeff Orkin wrote about this fantastic concept, and it was used in games such as F.E.A.R. and Fallout 3. It might be a bit overkill for your application, but I thought it was interesting.

http://web.media.mit.edu/~jorkin/goap.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜