如何处理MVC 2D游戏中对象的图形表示?

8

我正在使用MVC模式用Java制作2D游戏,在阅读和搜索后,我仍然找不到如何处理对象的图形表示的令人满意的答案。

例如,应该将每个对象(例如Player)分成PlayerModel(存储在Model中)和PlayerView(存储在View中)吗?

这看起来有点混乱,因为那么我将不得不跟踪哪些图形表示对象(例如“ScaryMonsterEnemyView”)连接到哪个逻辑表示对象(例如“ScaryMonsterEnemyModel”)。根据MVC,这真的是我应该这样做的吗?如果是,这个连接应该存储在哪里?在视图中吗?

我知道这可能是一个很傻的问题,但我想从一开始就尽可能做正确。谢谢帮忙 :)


1
也许你会发现这篇文章很有帮助..如果你还没有读过的话。 - tereško
@tereško 所以基本上 ScaryMonsterEnemyView 会持有 ScaryMonsterEnemyModel 吗? 我猜那也许是有道理的.. - tobes
在MVC中,视图不持有模型。视图仅从模型层接收数据。这些数据可以是从模型层发送的(经典MVC),也可以是由视图请求的(Model2 MVC)。 - tereško
@tereško 什么是模型层?也许我的术语不正确,让我重新表述一下。从您链接的文章中可以看到:“EntityRepresentation可以查看但不能更改实体的状态。”因此,我在先前的评论中所说的是,表示(存储在视图(?)中)需要一个变量来存储实体(存储在模型(?)中),以便“查看”/请求实体数据。 - tobes
3
“模型层”这个概念我无法简单地解释,这里提供的是PHP和Web方面的内容。也许你可以阅读《企业应用架构模式》(PoEAA)这本书。通过构造函数(直接或作为抽象的一部分),EntityRepresentation实例获取Entity实例。我认为你可以将其视为“存储”,但是EntityRepresentation实际上仅持有对该对象的处理程序或引用(取决于语言)。 - tereško
2个回答

4
如果我没有理解错的话,您基本上是在问如何将游戏拆分为模型-视图-控制器范例。简而言之,模型是您的游戏状态。在面向对象的术语中,您可以将模型视为游戏中的所有对象。控制器是应用于游戏状态(在本例中为所有游戏对象)的一组规则,在每个更新周期中进行。这可以实现为所有对象中称为update()的方法,或者它可以是在游戏循环中调用的函数,该函数系统地遍历所有需要更新的对象并更新它们。您还可以将控制器视为游戏循环本身。它调用所有内容进行更新,然后将其绘制到屏幕上并重复,除非满足某些条件,然后它告诉程序执行其他操作。通过这种方式,您几乎具有两个嵌套的MVC结构。一个控制程序流程通过菜单等,另一个专门用于游戏本身。
视图只是您的游戏的图形表示。这可以简单地是屏幕上的文本,但在您的情况下,它是2D图形。要实现这一点,您可以使每个对象也包含其图形状态,直接或通过封装。视图不会做更多的事情,只是查询所有对象的图形状态,然后将其传输到屏幕上。同样,这可以基于每个对象实现,例如称为draw()的方法,或者另一个直接从游戏循环调用的系统函数。常见做法是创建一个名为“ Sprite”或类似名称的对象来保存图形信息,并使每个绘制的游戏对象都具有个人实例。还要注意,视图不需要成为独立的对象。在游戏循环中调用的简单函数就足够了,尽管有时需要存储直接影响视图操作的信息(如窗口大小),在这种情况下,视图可以是对象。控制器也是如此。
还要记住,这些分区可以进一步分割以使生活更加简单。例如:控制器可以分为AI处理、移动更新和碰撞检查。视图可以分为游戏对象显示和HUD,而模型可以是所有对象+与游戏对象无关的所有状态(如分辨率、窗口大小、键配置等)。
我知道这可能有点过度,它可能还有额外的信息,但希望它回答了您的问题并给出了开始的想法。

1

模型和视图是两个对象的集合/类别/领域。

控制器提供了一组接口,用于对模型对象执行某些功能。如果需要,视图可以直接与模型对象交谈,了解它们的状态信息。

传统上,视图领域对应于GUI,包括按钮、表单、窗口等概念。在桌面环境中。

您的视图领域(或其中之一)将对应于您构建的3D环境。(树木、房屋、人物等)。这包括碰撞细节和物理学。这两者都需要与您的3D环境相关的几何形状。

在游戏中,这些对象很少需要与另一个领域中的对象协作。但是,例如,考虑电话。该对象将存在于您的3D环境中,但也将与描述“半通话”、“通道”、“开关”等的另一个领域协作。这些对象不属于您的视图领域,而属于单独的模型领域。

更相关的例子可能是某种得分系统,例如RPG统计数据,这将属于模型领域。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接