Model view controller 游戏:谁负责展示?

Model view controller 游戏:谁负责展示?,model-view-controller,coding-style,Model View Controller,Coding Style,实体应该知道如何绘制自己吗?我曾经使用过这种方法:它很简单而且有效,但是在学习了MVC模式之后,我对此感到不安。当所有的显示逻辑都隐藏在模型中时,很难改变艺术风格 我们可以引入一个视图类,它将level作为参数并绘制它,但这意味着它必须识别实体类型并引入一个“switch”语句,我知道这也是不好的 应该在哪里放置绘图代码,以一种可扩展、易于更改、干净且干燥的方式?MVC不一定非常适合游戏。MVC是为传统的GUI设计的,这些GUI通常不经常根据离散事件进行更新,而游戏更像是不断更新的模拟,演示需要

实体应该知道如何绘制自己吗?我曾经使用过这种方法:它很简单而且有效,但是在学习了MVC模式之后,我对此感到不安。当所有的显示逻辑都隐藏在模型中时,很难改变艺术风格

我们可以引入一个视图类,它将level作为参数并绘制它,但这意味着它必须识别实体类型并引入一个“switch”语句,我知道这也是不好的


应该在哪里放置绘图代码,以一种可扩展、易于更改、干净且干燥的方式?

MVC不一定非常适合游戏。MVC是为传统的GUI设计的,这些GUI通常不经常根据离散事件进行更新,而游戏更像是不断更新的模拟,演示需要立即反映这一点


尽管如此,您仍然没有理由不努力将状态和表示分开。实体不需要知道如何绘制它们自己,这意味着它们知道渲染操作,这是不必要的,但是应该可以询问它们如何看待这个时间点,然后使用该信息渲染场景。2D实体应该能够返回其当前动画帧。或者,三维实体应该能够返回其三维网格、位置和方向。这里不需要switch语句,只要您有可以返回到渲染器的通用表示。具有完全不同渲染算法的实体此时可能必须返回完全不同的对象。

在实体中使用abstract Draw()样式的方法,让它们决定如何绘制,这本身并没有什么问题,尤其是对于可能不会显著扩展的小型游戏。我在很多小项目中使用过这种方法,效果非常好

您可以对该策略进行改进,将游戏资源用作实际绘图操作的代理。例如,敌方实体可以通过其拥有的表示网格的资源对象延迟所有渲染;纹理/皮肤和效果也是如此


最近,我转而将实体用作定义其行为的接口的“哑”容器。播放器实体可能包含IMoveable、iControlable、IRenderable和更多接口,这些接口根据其包含的数据对该实体应用专门的操作。实体对此了解不多,所有执行都是在遍历场景图进行消隐/渲染时进行的。

通常我使用继承来解决这个问题

例如,在我正在处理的一个项目中,我正在使用测试驱动开发来编写游戏逻辑,并对渲染进行手动测试。下面的C#示例显示了大致的想法

class GameObjecet {
    // Logic, nicely unit tested.
}

class DrawableGameObject : GameObject {
    // Drawing logic - manual testing
}

这通常是我发现的最佳解决方案。这允许对代码进行测试,同时不会使游戏逻辑与呈现代码(如绘图、模型加载等)混淆。

随着各种工作室和团队开始使用新引擎,这个问题在游戏开发中仍然经常出现

简而言之,这取决于游戏实体的复杂程度。对于简单的实体,这并不重要

当你进入更复杂的实体时,你必须重新思考你的方法。通常,您希望抵制让uber循环遍历每个实体并调用某些更新/渲染/任何函数的冲动。除非每次更新、渲染或任何层次结构都完全相同,否则这根本不会缩放。这对于几何战争这样的游戏来说很好,但对于任何比这更复杂的游戏来说都不行

您要做的是为最通用的实体集合提取特定于用法的遍历。例如,如果要渲染场景,应该有一种从实体集合中提取所有可渲染实体的方法,然后以任意的批处理顺序渲染所有实体。物理、碰撞、人工智能等也是如此

一些有用的链接:


我强烈推荐两者;第一部分介绍了用组件构建游戏实体的设计原理,即渲染组件、物理组件、AI组件。第二部分讨论各种游戏实体方法的性能特征。

switch语句没有任何错误。switch语句在多个位置具有相同的结构,这通常意味着您应该使用虚拟函数。switch语句只是伪装的goto。Switch语句还不错。随着时间的推移,它们只会导致巨大的混乱-例如,它们是复制/粘贴磁铁。+1-很好的问题。这与问题没有直接关系,但如果您采用您描述的方法,谁应该负责处理纹理等资源?实体、渲染器或其他一些object?纹理是表示的实现细节,因此它们不会直接出现在实体中。通常,在某种资源管理器中,在为实体加载精灵或网格的位置加载这些资源。实体知道它使用哪个精灵或网格,精灵或网格知道它们使用哪个纹理。不知怎的,这是我第一次看到这个,我真的很喜欢它。提到可测试性+1。当设计选择时,太少的程序员会考虑。