如何组织游戏的代码以适应 MVC 模式?

我是一名大学新生,正在攻读计算机科学学位...在过去的几年里,我已经编写了很多程序,但最近我一直在更多地了解组织代码,设计模式,语言差异等理论思想。

我有一个Java类,所以我放弃了C++研究/开发,转而使用Java和JOGL(Java OpenGL)。太好了!但这不是重点。

我想做一个小型的角色扮演游戏,但这个问题确实适用于任何类型的游戏。如何以结构化的方式组织游戏对象,如模型-视图-控制器模式?它看起来是一个惊人的模式,使用非常广泛,很有意义,但我很难弄清楚如何实现它。

例如,我需要跟踪GL对象以绘制到屏幕上。我必须有实现MouseListener,MouseMotionListener,MouseWheelListener和KeyListener的类(或一个类,一个多合一的输入管理器)。我必须把我的游戏数据放在所有这些不同的类都可以访问和修改它的地方。如果有人按下键盘上的按钮,输入管理类需要以某种方式执行键映射到的操作;当需要绘制框架时,图形类需要找到一种方法来遍历所有不同的“事物”并绘制它们。

我最大的问题是GUI;它在哪里与这一切联系在一起?它类似于输入,但并不完全如此,它需要设置和获取实际游戏模拟的数据片段......更复杂的是,如果我决定尝试添加网络,它(类似于GUI)还需要访问大量数据以进行修改和读取...

哦,我只是很困惑。我不知道如何以面向对象的方式使所有这些协同工作......写出明显符合模式的东西很容易,但是当你有很多事情发生时,都与一个游戏循环有关,相互修改和游戏数据等等,......我甚至不知道了。也许我只是在做一个比实际更大的交易。

有没有人有这种感觉?请澄清我的情况,这样我就可以花更少的时间担心和不知道从哪里开始!

编辑:找到一个漂亮的图表,可能会帮助我弄清楚这一切...来源:(当心,PS文件!http://www.tucs.fi/publications/attachment.php?fname=TR553.ps.gz

编辑2:我也喜欢这个家伙对他如何计划他的MVC游戏的解释:http://interactivesection.wordpress.com/2007/11/19/dum-de-dum-drum-my-first-mvc-game-development/

编辑3:另一篇很棒的文章!http://dewitters.koonsolo.com/gamemvc.html


答案 1

将模型视为一种游戏 API 可能会帮助您。如果从一开始就没有为游戏指定UI,您的游戏将简化为什么?你提到你想到的是RPG,所以在这种情况下,你可以想象玩家角色,他/她的物品栏,法术,能力,NPC,甚至像地图和战斗规则这样的东西都是模型的一部分。它就像《大富翁》的规则和片段,没有最终游戏如何显示或用户将如何与之交互的细节。它就像Quake一样,是一组抽象的3D对象,在关卡中移动,计算了交叉点和碰撞等内容,但没有渲染,阴影或声音效果。

通过将所有这些放入模型中,游戏本身现在与UI无关。它可以挂接到像Rogue游戏那样的ASCII文本界面,或者类似于Zork的命令行UI,或者基于Web的3D UI。根据游戏机制的不同,其中一些UI可能是一个可怕的契合,但它们都是可能的。

视图层是 UI 相关层。它反映了您使用的UI的具体选择,并将非常致力于该技术。它可能负责读取模型的状态,并以 3D、ASCII 或图像和 HTML 绘制网页。它还负责显示玩家与游戏交互所需的任何控制机制。

控制器层是两者之间的粘合剂。它永远不应该包含任何实际的游戏逻辑,也不应该负责驱动 View 层。相反,它应该将在视图图层中执行的操作(单击按钮,单击屏幕区域,操纵杆操作等)转换为对模型执行的操作。例如,掉落物品,攻击NPC等等。它还负责收集数据并执行任何转换或处理,以使 View 图层更容易显示数据。

现在,我上面描述它的方式是,好像有一个非常独特的事件序列驱动着游戏,这可能只适合网页游戏。那是因为这就是我最近花时间做的事情。在一个不受用户请求和服务器响应(如网络)驱动的游戏中(例如,在用户机器上运行的游戏),您可能希望确保模型层很好地实现了观察者模式。例如,如果由于时间流逝而在模型中发生操作,则您可能不希望视图层不断轮询模型以获取更新。相反,通过使用观察者模式,模型可以在发生模型对象更改时通知任何观察者。这反过来又可以用来提示立即更新视图以反映更改。

然后,如果 60 秒的过去导致玩家的基地发生一些维修,基地可能会影响维修,并立即通知任何附加到它的观察者基地已经更新。视图可以附加为观察点,并注意它需要重新显示基础,因为它的状态已更改。通知本身可能包含足够的信息来更新视图,或者它可能必须转身并查阅模型才能更新,但结果将是相同的。


答案 2

你在那里相处得很好。基本上,问问自己一个问题:“如果我必须更改程序的某些部分,哪些代码会改变?

如果它在不更改基本数据的情况下更改其外观,则它位于视图中。如果数据可以通过多种方式查看,那就是模型。如果这是你的游戏方式,那么它就是控制。

因此,如果您用两个刀片还是一个刀片绘制“斧头”,那就是视图。如果是你用斧头造成多少生命值伤害,那就是模型。如果你是通过键入“s”还是通过右键单击来摆动斧头,那就是控制。