我有两个课程,人类和怪物。
都有一个名为MoveBehavior的属性
Human有HumanMoveBehavior,Monster有MonsterMoveBehavior
我希望HumanMoveBehavior从怪兽身上移动,并让MonsterMoveBehavior移动TOWARD Humans。
我遇到的问题是我应该在哪里移动代码?
在Human / Monster课程中?
使用这种方法,我有一个Move()方法,它接受游戏中所有实体的List,使用名为GetListOfOpponents(List allsprites)的方法决定它是Monster还是Human,然后运行GetNearestOpponent(List opponents);
但这看起来很麻烦。
我应该有一个SpriteController来决定精灵移动的位置吗?我不确定我需要把这段代码放在哪里:(
谢谢!
答案 0 :(得分:5)
您可以想到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
询问您放置的位置。< / p>
由于路径查找大部分时间是通过使用某些导航网格或指定网格完成的,因此GameObjectManager
可以返回特定网格,其中包含所有可导航点。你肯定不能定义每个怪物的所有位置。因为大多数时候,怪物并不完全知道每个人的位置(在现实生活中)。因此,知道哪些地方不合适确实很好,但知道每个人的位置,也会给你的AI带来太大的优势。
所以想想回到一个网格,其中包含要去的地方和不去的地方,而不是将这些东西保存在怪物/人类中。通过思考现实生活中的事情,始终检查你应该留在哪里。
答案 1 :(得分:0)
Valve认为,对于Half Life 2中的实体来说,处理这个问题的方式是更好的方法之一。它不是给每个AI单独的Move方法并调用它们,而是简单地调用Think()方法并让实体决定它需要做什么。
我会选择Marnix所说的并实现一个AIManager,它遍历游戏世界中每个活跃的AI,调用每个人的Think()方法。我不建议将您的Human类与“IMoveBehavior”接口,因为将它抽象为“WorldEntity”抽象类会更好。
您可能拥有无形实体来控制自动波,触发器,灯光等等,但有些实体会在世界上占有一席之地。这些人将有一个矢量来识别他们的位置。让AI的Think()方法调用自己的move()方法,但保持私有。唯一需要考虑移动的是AI本身。
如果你想鼓励AI移出Think)方法,我会提出一些必要的建议,例如面向目标的行动计划(GOAP)系统。杰夫奥金写到了这个梦幻般的概念,并在F.E.A.R等游戏中使用过。对你的应用程序来说可能有点矫枉过正,但我认为这很有趣。