如何使用as3 addeventlistener在另一个类中调用方法?

时间:2013-05-20 17:59:33

标签: actionscript-3 navigation mouseevent addeventlistener document-class

我有两个班级

主要课程 - 课堂游戏

Public Class Game
{

    private var m_navButtons:NavButtons;

    public function Game( )
    {
         setUpLevelSelect();


    }

    public function setUpLevelSelect():void
    {
        addChild(levelsMovieClip);
        // when i click a level it plays the game

    }
    public function playGame():void
    {
       // plays game and add navButtons
       m_navButtons = new NavButtons( this.stage );

    }

}

另一个为游戏阶段添加小导航按钮的类,名为navButtons

public class NavButtons extends MovieClip
{
  public function NavButtons( stage:Stage )
  {
      // addNavigation to stage
      m_stage = stage;

      m_stage.addChild( icon );

      // addeventlisteners
      icon.backButton.addEventListener( MouseEvent.CLICK, goBackToLevelSelect );

  }

  public function goBackToLevelSelect( event:MouseEvent ):void
  {

// now i would like to call Game.setUpLevelSelect();


// but when i click the icon.backButton it says Cannot access a property or method of a null reference 
  }

}

在NavButtons的顶部,我放了public var game:Game;

我有一种感觉,因为我想回到我的主要文档课“游戏”,但我不知道如何绕过它。

1 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。

第一种方式是派遣一个事件。这是孩子与其父母沟通的正确方式。

游戏中的

navButtons.addEventListener( "customEventTypeHere", this.setUpLevelSelect ); 
NavButtons中的

public function goBackToLevelSelect( event:MouseEvent ):void
{
    this.dispatchEvent( new Event( "customEventTypeHere" ) );
}

您还可以将MouseEvent侦听器直接附加到Game中的按钮而不是NavButtons中。显然,您需要将backButton公开。这在技术上是正确的,但它删除了抽象级别,因为父级现在依赖于类中的backButton对象

在游戏中:

navButtons.backButton.addEventListener( MouseEvent.CLICK, this.setUpLevelSelect );

您可以通过构造函数传递setUpLevelSelect。这被称为回调,而不是监听器。这是处理此问题的好方法,因为这意味着NavButtons类可以轻松地被其他类使用。您只需传入适当的回调,它就会按您期望的方式工作。它确实有一个引用函数的缺点,这意味着要清理垃圾收集的另一件事。

public var backButtonCallback:Function;
public function NavButton( stage:Stage, backButtonCallback:Function ) {
    this.backButtonCallback = backButtonCallback;
}

public function goBackToLevelSelect( event:MouseEvent ):void
{
    this.backButtonCallback();
}

最后一种方式是不应该在这里或在很多地方使用的方式,老实说。但它是一种选择,即使它确实违反了基本的OOP原则。基本上,您通过将Game的实例存储在静态属性中并通过那里访问您的公共函数,将Game变为部分Singleton。这是推荐,除非您有特定的理由这样做,并且只有在只有一个游戏实例时才能工作。

在游戏中:

public static var instance:Game;

public function Game() {
    instance = this;
}

在NavButtons中:

public function goBackToLevelSelect( event:MouseEvent ):void
{
    Game.instance.setUpLevelSelect();
}

我可以想到其他几种方法,但这些肯定是你应该考虑的四种方法。我个人的建议是使用第一个建议