2

目前我正在编写一个应用程序。如果我想避免单例,我是否必须简单地传递周围所有内容的引用?

例如,

我有一个“主要”课程。
类:主
+----屏幕
+----相机
+----地形
+----车辆
+----物理世界

它包含我的相机、地形和车辆等类。现在,我在创建 Terrain 对象时遇到了问题。Terrain 想要访问 Main 类 Screen 对象,以便将其 Terrain Graphics 添加到屏幕上。它还想知道 Camera 对象何时绘制,以便知道绘制它的比例。它还想了解我的 PhysicsWorld 对象,以便将自己添加到物理引擎中。

我是否必须总是在构造函数之间来回拉动这些对象?我的意思是,当我创建一个地形对象时,我是否只需要传递我的屏幕对象、我的物理世界、相机等?

我有另一个随机场景,现在.. 在我的 Vehicle 类中,我需要在 Main 类上调用 Restart() 方法。这是否意味着我必须将 main 实例传递给 Vehicle?真的??

不断地向我的课程传递 4-5 件东西感觉很麻烦,尤其是在我现在的场景中,我拥有的几乎每个游戏内对象都需要屏幕、物理、相机信息等。

有什么建议么?

4

4 回答 4

2

不断地向我的课程传递 4-5 件东西感觉很麻烦,尤其是在我现在的场景中,我拥有的几乎每个游戏内对象都需要屏幕、物理、相机信息等。那么要问的正确问题是“为什么我的所有班级都需要全部 5 个对象吗?” 为什么地球上的每个内部物体都需要上述任何东西?游戏中的对象需要一个位置以及处理其行为所需的任何东西。然后一个单独的渲染器可以,你知道,渲染,对象。这意味着只有渲染器需要相机信息和屏幕。

物理学可以走任何一条路。您可以有一个单独的物理实体来更新游戏对象,或者您可以将该物理对象传递给每个游戏对象。但是,即使您确实传递了它,我们也只剩下列出的三个对象之一。:)

这就是为什么最好避免使用全局变量和单例。它们掩盖了您的依赖关系,因此您的对象之间的依赖关系最终比您实际需要的要多得多。然后几乎不可能删除全局变量。

但是,如果您坚持使用全局变量,请帮自己一个忙,至少避免使用单例。您不需要单例强制执行的附加约束。

Terrain 想要访问 Main 类 Screen 对象,以便将其 Terrain Graphics 添加到屏幕上。它还想知道 Camera 对象何时绘制,以便知道绘制它的比例。它还想了解我的 PhysicsWorld 对象,以便将自己添加到物理引擎中。

地形对象需要知道一件事:地形是什么样的。其他人可以负责渲染它。当然,有人需要了解相机、屏幕和地形图形,这表明同一个对象可能能够执行涉及这些对象的其他任务(例如其他渲染任务)。为什么地形要关心它的绘制比例?它需要知道游戏中的比例,而不是相机空间中的比例。为什么其他人不能将地形添加到物理引擎中?主要功能甚至可以做到这一点。创建地形,创建物理引擎,使用物理引擎注册地形,开始游戏。

于 2009-03-07T02:21:59.293 回答
1

我不知道 ActionScript,但假设变量是通过引用传递的,那么您至少可以构建一个包含 Camera、Screen、Terrain、PhysicsWorld 的“Environment”类,并将其传递给实例。

于 2009-03-07T01:24:22.897 回答
0

我有完全相同的问题(巧合的是,在 actionscript 3 中)。

我一直在为 Flash 开发 RTS,并且发现自己需要传递对每个新类的大量引用(例如,gameGrid、currentSelection、visibleUnits 等)。

我最终意识到我真正应该做的是让每个类都维护它自己的属性,而不是传递对这些类的引用(以及对象)。

但无论如何,现在我正在做的是在一个名为 RTSGlobals 的类中包含对常用对象(如主舞台、界面、引擎和显示区域)的引用的静态变量。我还在其中放置了诸如屏幕尺寸之类的常量。

我知道这并不能真正回答您的问题,但我认为有时值得忽略一些 OOP 良好实践以支持有效的解决方案。

如果有人有一个很好的实践解决方案,请告诉:)

于 2009-03-07T03:55:19.117 回答
0

我建议你看看 XNA 的示例项目(google it)。它们设计精良,可能会给您一些提示。

此外,由于您使用的是 AS3,因此您可以使用事件系统向其他实体发送消息。例如,不要将 Main 传递给 Vehicle 类,而是让 Main(或其他任何感兴趣的东西)成为 Vehicle 类的侦听器。然后,假设发生车祸,您想重新开始游戏,调度一个事件,例如 CAR_CRASHED。你的汽车的听众应该根据这个消息做一些事情。如果您想了解事件系统,请键入 EventDispatcher,突出显示它并在 Flash IDE 中按 F1。

于 2009-05-29T01:20:38.690 回答