避免全球状态

时间:2009-03-07 01:14:31

标签: actionscript-3 singleton global-variables

目前我正在编写应用程序。如果我想避免单身人士,我是否必须简单地传递所有内容的参考?

例如,

我有一个“主要”课程 课程:主要
+ ----屏幕
+ ----相机
+ ----地形
+ ----车辆
+ ---- PhysicsWorld

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

我是否必须始终在构造函数之间来回拖动这些对象?我的意思是,当我创建一个Terrain对象时,我是否只需要绕过我的屏幕对象,物理世界,相机等?

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

经常不得不将4-5个东西传递给我的课程感觉很麻烦,特别是在我现在几乎每个游戏对象都需要屏幕,物理,相机信息等的场景中。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

  

经常有麻烦   把4-5件东西传给我的班级,   特别是在我现在的情景中   几乎所有我在游戏中的对象   需要屏幕,物理,相机信息,   等等   然后要问的正确问题是“为什么我需要所有课程中的所有5个对象?”   为什么在地球上每个in-gmae对象都需要提到上述任何东西?游戏内对象需要一个位置以及处理其行为所需的任何位置。然后,单独的渲染器可以渲染对象。这意味着只有渲染器需要摄像机信息和屏幕。

物理学可以采用任何一种方式。您可以拥有一个单独的物理实体来更新游戏对象,或者您可以将该物理对象传递给每个游戏对象。但是,即使你确实传了这些,我们也只是列出了三个对象中的一个。 :)

这就是为什么通常最好避免使用全局和单身人士的原因。它们掩盖了您的依赖关系,因此最终您的对象之间的依赖关系远远超过您实际需要的依赖关系。然后,删除全局变量几乎是不可能的。

然而,如果你坚持使用全局,请帮自己一个忙,至少避免单身。您不需要单例强制执行的其他约束。

  

Terrain想要访问Main类   屏幕对象,所以它可以添加它   地形图形到屏幕。它   也想知道相机   对象当它正在绘制时   知道绘制它的比例。它也是   想知道我的PhysicsWorld   对象所以它可以将自己添加到   物理引擎。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

我有完全相同的问题(同样在动作3中,巧合)。

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

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

但无论如何,现在我正在做的是使用包含对常用对象的引用的静态变量,例如名为RTSGlobals的类中的主阶段,接口,引擎和显示区域。我也在那里放置屏幕尺寸等常量。

我知道这并没有真正回答你的问题,但我认为有时值得忽略一些OOP良好做法,转而采用有效的解决方案。

如果有人确实有一个好的练习解决方案,请告诉:)

答案 3 :(得分:0)

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

此外,由于您使用的是AS3,因此可以使用事件系统将消息分发给其他实体。例如,不要将Main传递给Vehicle类,而是让您的Main(或其他任何感兴趣的人)成为Vehicle类的监听器。然后,让我们说车祸,你想重新启动游戏,派遣一个事件,例如CAR_CRASHED。你的汽车听众应该根据这条消息做点什么。如果要了解事件系统,请键入EventDispatcher,突出显示它并在Flash IDE中单击F1。