我正在开发一个简单的游戏设计,我想将我的游戏对象分解为更多可重用的组件。但是我一直在坚持如何实现我想到的设计。这是一个例子:
我有一个Logger对象,其工作只是存储一个消息列表并将它们呈现给屏幕。你知道,记录。最初Logger只保留了列表,游戏循环呈现了它的内容。然后我将渲染逻辑移动到Logger.Draw()方法中,现在我想将它进一步移动到LoggerRenderer对象中。
实际上,我想让游戏循环调用RenderAll,然后调用Logger.Render,它将调用LoggerRenderer.Render并最终输出文本。因此Logger需要包含Renderer对象,但Renderer需要访问Logger的状态(消息队列)才能呈现。
我该如何解决?我应该将消息队列和其他状态信息显式传递给Render方法吗?或者游戏循环应该直接调用渲染器并且它链接回记录器,但RenderAll方法实际上从未真正看到记录器对象本身?
这有点像Command模式,但我非常惹恼它。
答案 0 :(得分:2)
或者游戏循环应该直接调用渲染器并且它链接回记录器,但RenderAll方法实际上从未真正看到记录器对象本身?
这一个。
答案 1 :(得分:1)
任何时候你有一个对象需要访问另一个对象的内部,你应该考虑功能羡慕的代码味道。不要那样做。
如果你真的需要一个LogRenderer,让它一次只渲染一条消息,让你的日志根据需要调用它。
E.g。日志说“对于每条消息,渲染器 - > RenderMessage(消息)”。
这假定Log拥有LogRenderer。如果你有其他一些架构,那么你可能需要稍微改变一些东西,但努力将Feature Envy保持在最低限度。
答案 2 :(得分:0)
以下是我将如何做到这一点
class Logger {
List<Message> messages;
Message[] getMostRecent(int numMostRecent) { ... }
}
class MyGame {
void draw() {
// all my ui stuff
Message[] messagesToRender = myLogger.getMostRecent(numRowsInLogWindow);
String formattedMessages = magicalFormattingIfNecessary(messagesToRender);
logWindow.setText(formattedMessages);
}
}
关闭拆分对象很好,但对于像消息日志这样简单的事情,你最好还是保持简单明了。我已经监督了几十个游戏的开发,而且大多数问题都来自它的设计过于复杂。
如果要创建MessageFormatter对象,可以这样做,但前提是您需要容纳多种格式。
注意:是的,我的伪代码实际上是Java。根据需要进行调整=)