0

我有一个Main类和一个GameScreen类。在GameScreen类中,我有一个让用户返回主菜单的按钮。但是,我的gotoMainMenu函数位于Main类中。我尝试将gotoMainMenu函数设为静态,但在该函数内部我调用非静态函数。

目前我有这段代码将gotoMainMenu函数传递给我的gameScreen对象:

gameScreen = new GameScreen(gotoMainMenu);

GameScreen构造函数中,我将其分配给实例变量,然后使用该实例变量作为第二个参数添加事件侦听器,如下所示:

backArrowButton.addEventListener(MouseEvent.CLICK, gotoMainMenuMainFunction);

这是一个好方法吗?如果没有,您能否提供另一种不被认为是错误编码的解决方案?

我有另一个非常相似的问题。我有一个Hero类,它需要访问我的GameScreen类中的许多变量。我知道静态变量是一种解决方法,但有人告诉我这是不好的编码,静态变量只能用于常量。

目前,我将实例变量作为参数传递,如下所示:

hero = new Hero(levelData, map, gameCont);

然后在Hero类中,我将这些参数分配给实例变量,这与我传入函数的方式非常相似。这些变量引用同一个对象。我需要将原始数据类型传递给 onEnterFrame 函数,如下所示:

hero.onEnterFrame(up, left, right, mouse);

这样做的问题是我不喜欢将引用同一对象的实例变量存储在 2 个单独的类中。我觉得有更好的方法来做到这一点。请提供这两个问题的解决方案,并确保它不被视为错误编码。

4

2 回答 2

0

传递引用本身并不是坏的编码。而且每个引用只占用几个字节的内存。

以这种方式使用引用的问题是您的代码变得耦合,从长远来看,您不希望这样。当然,如果您有一个包含 3 个类的项目,这并不重要,但在较大的项目中,保持头脑清醒并能够重用代码变得至关重要。

为了解决这些耦合问题,很久以前有些人发明了许多不同的设计模式。为了解决您的通信问题,您可以使用例如观察者模式单例模式

另一个替代传递引用的选项是使用事件。如果您采用这种方式,我强烈建议您使用Robert Penner 的 Signals

于 2013-10-31T06:06:28.327 回答
0

首先,您对第一个问题的解决方案确实被认为是一种糟糕的编码习惯。

现在让我们继续使用解决问题的好方法。正如我所见,您正在课堂上创建一个GameScreen实例。Main这意味着您有对该对象的引用,因此您可以为自定义事件添加一个事件侦听器,告诉您的Main类返回到主菜单。您的代码将是这样的:

// you just create your instance, without the Function parameter
gameScreen = new GameScreen();

// then you add an event listener for your custom event
gameScreen.addEventListener(MyGameEvent.GOTO_MAIN_MENU, gotoMainMenu);

现在请注意,这会将您的自定义事件的实例作为参数传递给该gotoMainMenu方法,因此您的gotoMainMenu方法的定义应该是这样的:

private function gotoMainMenu(e:MyGameEvent):void {...}
// or if you'd like to call this method on a click, use the parent of all events Event class:
private function gotoMainMenu(e:Event):void {...}

请注意,我们MyGameEvent用更通用的类更改了Event类。

现在,如果需要,您必须创建MyGameEvent以添加自定义类型甚至自定义数据。为此,您必须Event像这样扩展类:

package
{
    import flash.events.Event;

    public class MyGameEvent extends Event
    {
        public static const GOTO_MAIN_MENU:String = "MyGameEvent.GOTO_MAIN_MENU";

        public function MyGameEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false)
        {
            super(type, bubbles, cancelable);
        }
    }
}

GameScreen当您需要从刚刚调用从类dispatchEvent继承的方法返回主菜单时(并且也有此方法,因为它们继承):EventDispatcherSpritesMovieClipsEventDispatcher

dispatchEvent(new MyGameEvent(MyGameEvent.GOTO_MAIN_MENU));

如果编译器在此调用中给您一个错误,请确保您的GameScreen类扩展了以下之一EventDispatcherSpriteMovieClip.

传递对您的Hero类的引用并没有那么糟糕,它在大型项目中可能会变得很麻烦,因为它会耦合您的代码,但您可以使用一些设计模式作为解决方案,正如 Pier 建议的那样。

于 2013-10-31T06:15:39.800 回答