2010-02-03 167 views
16

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

可以引入一个视图类,该视图类将层次作为参数并绘制它,但这意味着它必须识别实体类型并引入一个“switch”语句,我学到的语言也很糟糕。

哪里应该绘制一个地方代码,以一种可扩展,易于更改,干净和干燥的方式?

+1

switch语句没有任何问题。在多个地方具有相同结构的switch语句存在错误,这通常意味着您应该使用虚函数。 – MSN 2010-02-03 18:25:50

+0

switch语句只是一个伪装的转换。开关语句不错。随着时间的推移,它们只会导致巨大的混乱 - 例如它们是复制/粘贴*磁铁*。 – sylvanaar 2010-02-03 18:59:04

+0

+1 - 优秀的问题。 – Finglas 2010-02-03 20:13:59

回答

5

Theres在你的实体中有一个抽象的Draw()风格的方法没有任何内在的错误,它们可以让他们决定如何绘制它们,特别是对于可能不会显着扩展的小型游戏。我已经在很多小项目中使用了这种方法,并且效果很好。

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

我最近转而将我的实体用作定义其行为的接口的“哑”容器。玩家实体可能包含IMoveable,IControllable,IRenderable以及更多的接口,这些接口只是根据其包含的数据对该实体应用专门的操作。实体对此并不十分了解,并且在场景图遍历用于剔除/呈现时,所有执行都会发生。

3

MVC不一定非常适合游戏。 MVC是为传统GUI而设计的,通常基于离散事件更新,而游戏更像是仿真,其中不断进行更新,演示需要立即反映。

尽管如此,你仍然没有理由不再努力将状态与演示分开。实体不需要知道如何绘制自己 - 这意味着他们知道渲染操作,这是不必要的 - 但应该可以问问他们如何看待此时间点,然后使用该信息渲染场景。例如。 2D实体应该能够返回其当前动画帧。或者3D实体应该能够返回其三维网格,位置和方向。这里不需要switch语句,只要您具有可以返回到渲染器的泛型表示形式即可。具有截然不同渲染算法的实体可能不得不在这一点上返回相当不同的对象。

+0

这与问题没有直接关系,但如果采用您描述的方法,谁应该负责处理纹理等资源?实体,渲染器还是其他对象? – 2010-02-03 19:39:58

+0

纹理是演示文稿的实现细节,因此它们不会直接位于实体中。通常你会在某些资源管理器中加载这些资源,这些资源管理器会在加载实体的精灵或网格的位置加载。实体知道它使用哪个精灵或者网格,并且精灵或者网格知道他们使用了哪些纹理。 – Kylotan 2010-02-03 23:22:38

3

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

例如,在我正在使用测试驱动开发编写游戏逻辑的一个项目中,通过手动测试渲染。下面这个C#示例显示了大概的想法。

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

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

这通常是我发现的最佳解决方案。这使得代码可以被测试,而不会用诸如绘图,模型加载等表示代码来混淆游戏逻辑......

+0

不知何故,这是我第一次看到这个,我真的很喜欢它。 – Ricket 2010-02-04 21:58:50

+0

提及可测性。很少有程序员认为在做设计选择时。 – 2010-06-04 17:11:38

7

这个问题在游戏开发中经常出现,因为各种工作室和组在新引擎上启动。

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

当你进入更复杂的实体时,你必须重新思考你的方法。一般来说,你会想要抵制拥有循环遍历每个实体的uber循环的冲动,并调用一些更新/渲染/任何函数。除非每次更新,渲染或任何层次结构完全相同,否则这根本无法扩展。对于像几何战争这样的游戏来说,这很好,但不适用于比这更复杂的任何事情。

你想要做的是给出最一般的实体集合提取特定于使用情况的遍历。例如,如果你想渲染场景,你应该有一种方法来从实体集合中提取所有可渲染的实体,然后以一些任意的可按顺序渲染它们。这同样适用于物理,碰撞,AI等

一些有用的链接:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf

我强烈建议两者;首先进入构建游戏实体出组件的设计原理,即渲染组件,物理组件,AI组件。第二个涉及各种游戏实体方法的性能特征。