它可能是模型的一部分,因为它是游戏业务逻辑的一部分。
它可能是控制器的一部分,因为它可以被视为模拟玩家输入,这将被视为控制器的一部分,对吧?还是会?
一个普通的敌人呢,比如马里奥里的 goomba?
更新:哇,这真的不是我期待的答案。据我所知,人工智能是自主游戏系统的内部部分,因此是模型。我仍然不相信。
它可能是模型的一部分,因为它是游戏业务逻辑的一部分。
它可能是控制器的一部分,因为它可以被视为模拟玩家输入,这将被视为控制器的一部分,对吧?还是会?
一个普通的敌人呢,比如马里奥里的 goomba?
更新:哇,这真的不是我期待的答案。据我所知,人工智能是自主游戏系统的内部部分,因此是模型。我仍然不相信。
MVC 非常适合作为大量应用程序的架构。一些应用程序可能会发现 MVC 非常适合外部接口,尤其是作为更复杂架构的一部分的用户接口。
如果您发现自己试图将问题“强制拟合”到模式中,那么它可能不是正确的模式。为 UI 使用 MVC - 为 AI 使用其他模式(消息总线或观察者/侦听器等)或其他 OO 技术(@Bill the Lizard 的策略建议仍然适用)。
使用您的整个工具箱 - 而不仅仅是锤子。;-)
想象一个简单的游戏,比如井字游戏,您希望在其中玩不同的计算机难度级别。如果您将每个难度级别都设置为Strategy,则很容易放入不同的实现中。
敌方 AI有一个模型——它的智能内脏指定了如何玩游戏——它使用人类玩家和 NPC 都可以使用的控制器来操纵它在游戏环境中的状态。
请记住,MVC 最初纯粹是一种 GUI 架构模式。因此,它不能很好地映射到人工智能、网络或其他方面也就不足为奇了。但是在这里使用它仍然有一些好处。但是代码实现了什么并不像它在链中的位置那么重要。仅仅因为某些东西看起来像是内部的,并不意味着它是内部的,因此不应被视为内部的。
例如。如果您正在编写一个机器人,那么您很可能基本上只是在编写脚本来操纵角色。所以从这个意义上说,脚本接口是预先存在的控制器,你的脚本完全是外部的。你甚至不用靠近模型来编写高级 AI。
现在,如果您是最初的程序员,必须编写低级 AI 功能,该功能由玩家交互(例如,点击某处开始行走)或机器人风格的脚本触发,那么您将一直在编写进入模型。
将任何单一概念(例如“AI”)从模型、控制器一直延伸到操纵控制器的任何人或任何事物,这似乎是不直观的,但是当您尝试将两个非常不同的概念映射到彼此。很明显,当您从开发人员的角度来看时,他们试图为非玩家角色呈现与玩家角色相同的界面 - 最终,人工智能必须同时包含外部演员的高级决策除了系统内的玩家和非玩家通常存在的低级实现之外,该系统还将进行。
在我看来,它就像是在模拟人类玩家,因此它应该与人类玩家处于相同的位置。因此,它是与控制器交互的外部元素。(出于显而易见的原因,显示器实际上并不是必需的。)
编辑:实际上,我收回了这一点。它将有一个显示器,只是不是一个人类可读的显示器。“显示器”将负责将游戏状态信息传达给 AI,即使这意味着将序列化数据流式传输给它。
第 2 部分:哦,我明白了……这和我想的 AI 类型不太一样。我想它仍然可以以相同的方式处理,但这将迫使新功能在控制器中公开,这可能没有意义。(例如,控制器必须公开移动玩家单位和计算机单位。)
我会将行为放入模型中:
Goomba.move()
{
/* Move Goomba forward one unit. */
}
然后对该行为的调用进入控制器。
Controller.advanceTime()
{
foreach(Goomba goomba in state.getGoombas())
{
goomba.move();
}
}
敌方 AI 模型将了解游戏规则并根据这些规则改变其内部状态。游戏控制器向 AI 提供外部游戏状态的知识,它可以用来决定如何改变其内部状态。
(我首先在这里写的:)
与游戏世界交互的 AI 部分将在控制器中。作为自主代理做出决策的人工智能部分将在模型中。控制器将根据其决策所需的状态更新 AI 模型,并且控制器还将根据 AI 模型中的任何更改修改游戏并渲染视图。
对于 Goomba,游戏控制器将使用马里奥的位置(如果它在它的视线内)更新 Goomba 模型,并且 Goomba 模型将自行更新它打算移动的位置。如果没有任何障碍物,控制器将移动 Goomba(即更新模型的位置)并使用 Goomba 的新状态渲染视图。
我不确定它在哪里适合 MVC。这个伪代码是我如何完成 A* 路径查找 AI 的一个极其简化的版本。
sprite {
x,y
image // this object contains everything about drawing
path[] // an array of path nodes generated by my AI
onNode(node) {
if (x == node.x) && (y == node.y) return true
return false
}
update () {
moveto(path.last())
if (onNode(path.last())) path.pop()
if (path.empty()) path = doAI()
}
doAI() {
...
return newPath
}
moveto(node) {
...
}
draw (screen) {
if (screen.over(x, y)) image.draw(x-screen.x, y-screen.y)
}
}
screen = //something the platform would create
spriteCollection = //my game objects
foreach (sprite in spriteCollection) {
sprite.update()
sprite.draw(screen)
}
在我看来,在任何 MVC 实现中,模型都应该包含域逻辑——只要它是自主对象(逻辑被固定在方法中)或套接字流包装器(逻辑是通过外部资源执行的——是的,想想多人游戏) . 控制器应该用作基于一些外部变量(例如 CLI 参数、事件调度程序)的模型的调用者/处理程序。然后将所需的数据(作为数组、序列化变量或某种数据传输对象)返回到正确的视图(游戏屏幕、控制台终端)。
干杯,艾伦
两者都不。我会将 AI 编程为通过控制器与模型通信的独立代理。或者,如果您愿意,AI 是A模型,但不是模型。