将渲染代码与实际游戏引擎/逻辑代码分开的最佳方法是什么?将它们分开是不是一个好主意?
假设我们有一个名为Knight的游戏对象。必须在屏幕上呈现骑士以供用户查看。我们现在有两个选择。要么我们给骑士一个我们可以调用的Render/Draw
方法,要么我们创建一个渲染所有骑士的渲染器类。
在两者分开的场景中,骑士应该还包含渲染他所需的所有信息,还是应该将它分开?
在我们创建的最后一个项目中,我们决定让渲染对象所需的所有信息都存储在对象本身中,但我们有一个单独的组件来实际读取该信息并渲染对象。该对象将包含大小,旋转,缩放以及当前正在播放的动画等信息,并且基于此,渲染器对象将构成屏幕。
像XNA这样的框架似乎认为加入对象和渲染是一个好主意,但是我们害怕被绑定到特定的渲染框架,而构建一个单独的渲染组件使我们可以更自由地在任何框架中更改框架。给定时间。
答案 0 :(得分:21)
我会创建一个单独的KnightRenderer
类。优点:
Knight
他自己甚至可能在游戏服务器上运行,根本不了解渲染。 KnightRenderer
需要了解Knight
(位置,状态)的所有内容必须在Knight
中公开阅读。
特定于渲染的属性将进入KnightRenderer
类。例如,也许你想让骑士在被击中时闪光,所以你需要存储一个计数器或时间值。
答案 1 :(得分:6)
我会努力使您的对象尽可能通用,并尽可能避免将游戏事实编码到您的代码中。
E.g。你有一个Entity或Object或Actor类,该类有一个指向其决策的指针(它的AI)和一个指向它的图形表示的指针。
它的决策必然与游戏事实有关;事实上它是游戏事实的一部分。因此,这可能是您可能将决策者命名为“KnightAi”的地方。
另一方面,图形表示只是一些图形。它将与其他所有实体相同。你有一个模型或一些位图和一些动画或不...这将被称为“模型”之类的东西,并将加载它被告知的信息加载定义实体对玩家的样子。当谈到渲染你的骑士与你的马而不是城堡时,你可能会发现他们只是用不同的数据做同样的事情。他们拥有的各种数据甚至都是一样的,只是内容不同。
假设您的实体都表示为圆圈。你可以让他们指向一个CircleRenderer,它采用了应该绘制的大小。您不会为您想要的每个不同大小(或颜色或其他)的圆圈创建不同的渲染器类!
答案 2 :(得分:6)
我知道我迟到了,但对于未来的读者,你可能会对我写的教程感兴趣。
我不是真正的专家,但这是我看到正确分离关注点的方式:
http://aurelienribon.wordpress.com/2011/04/26/logic-vs-render-separation-of-concerns/