我有两个班级,人类和怪物。
两者都有一个名为MoveBehavior的属性
人类有HumanMoveBehavior,怪物有MonsterMoveBehavior
我希望HumanMoveBehavior远离怪物,MonsterMoveBehavior向人类靠拢。
我遇到的问题是我应该把我的代码放在哪里移动?
在人类/怪物课上?
使用这种方法,我有一个Move()方法,它获取游戏中所有实体的列表,使用名为GetListOfOpponents(列出所有精灵)的方法来判断它是怪物还是人类,然后运行GetNearestOpponent(列出对手);
但这看起来真的很乱。
我应该有一个决定Sprite移动到哪里的SpriteController吗?我不确定我需要把这段代码放在哪里:(
谢谢!
发布于 2011-01-18 01:27:42
你可以想象一个AIManager,它只是写着:
foreach(GameObject go in m_myObjects) // m_myObjects is a list of all objects that require updating
{
go.Update(); // standard GameObject function
}在此之后,每个类都应该负责自己的代码段。所以更新在类本身中起作用。
所以人类说:
// 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();
}通过使用接口,您可以使特定的语言部分成为类的一部分,而不需要创建一些将为您处理这些内容的类。当然这是可能的。但在现实生活中,人类/怪物是移动的,而不是他携带的某个物体。
更新
对评论的回答。因为有一个AIManager,甚至一个完整的GameObjectManager来维护所有的GameObjects会很好,你可以向AIManager询问你不能去的地方。
因为寻路在大多数情况下是通过使用一些导航网格或指定的网格来完成的,所以GameObjectManager可以返回包含所有可导航点的特定网格。你当然不应该定义每个怪物的所有位置。因为大多数时候,怪物并不确切地知道每个人在哪里(在现实生活中)。因此,知道哪里不去确实很好,但知道每个人都在哪里,也会给你的人工智能带来太多优势。
因此,考虑返回一个带有要去和不要去的点的网格,而不是在怪物/人类内部维护这些东西。总是检查你应该把什么放在哪里,通过思考什么是现实生活中的东西。
发布于 2011-01-30 16:34:01
Valve为“半条命2”中的实体处理这个问题的方式,我认为是更好的方式之一。它不是给每个AI提供它自己的单独的移动方法并调用这些方法,而是简单地调用Think()方法,让实体决定它需要做什么。
我会按照Marnix所说的去做,并实现一个AIManager,它遍历游戏世界中每个活动的AI,调用每个AI的Think()方法。我不建议将你的人类类与一个"IMoveBehavior“接口,因为将它抽象成一个"WorldEntity”抽象类会更好。
你可能有一些看不见的实体来控制诸如自动保存、触发器、照明等东西,但有些实体将在世界上占有一席之地。这些人会有一个矢量来识别他们的位置。让AI的Think()方法调用它自己的move()方法,但保持它是私有的。唯一需要考虑移动的是AI本身。
如果你想鼓励人工智能走出Think(思考)方法,我会建议一些势在必行的方法,比如目标导向的行动计划(GOAP)系统。Jeff Orkin写了关于这个奇妙的概念,它被用在像F.E.A.R.和Fallout 3这样的游戏中。它对你的应用程序来说可能有点夸张,但我认为它很有趣。
http://web.media.mit.edu/~jorkin/goap.html
https://stackoverflow.com/questions/4715899
复制相似问题