公共功能访问失败

时间:2012-09-10 15:27:50

标签: actionscript-3 flash

我遇到这种情况,我在主类中声明了一个如下所示的函数:

public class Main extends MovieClip
{

    public static var instance:Main;

    public function Main()
    {
        // constructor code
        welcomeScreen();
        instance = this;
    }

    public final function welcomeScreen():void
    {
        //some code in here
    }

    public final function startLevelOne():void 
    {
        //some other code here
    }


}

在其他一些类中,我使用此语句来触发重置:

restart.addEventListener('click', function() {                                      
     Main.instance.welcomeScreen();
});

不知怎的,在另一个课程中,我尝试使用相同的语句来启动“开始”一节'但它似乎无法正常工作并给出了错误的错误:

1195: Attempted access of inaccessible method startLevelOne through a reference with static type Main.

有什么想法吗?

更新#1

我尝试访问该函数的类是完整的:

public class LevelBrief extends MovieClip
{

    public function LevelBrief()
    {
        // constructor code
        startBut.addEventListener('click', function() {
            Main.instance.startLevelOne();
        });
    }
}

更新#2

我已在此处粘贴主要定义的完整代码http://pastebin.com/s6hGv7sT

此处可以找到其他课程http://pastebin.com/s6h3Pwbp

更新#3

即使问题已通过解决方法解决,我仍然无法理解问题出在哪里。

5 个答案:

答案 0 :(得分:4)

我建议保留静态实例(单例),并以事件为基础。现在你公开所有的功能,这是不可取的。使用自定义事件并不难。看看这是 Main 类的外观:

public class Main extends MovieClip
{
    public function Main()
    {
        this.addEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
    }

    public function handleAddedToStage(event:Event)
    {
        this.removeEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);

        this.showWelcomeScreen();

        stage.addEventListener(ScreenEvent.SHOW_WELCOME_SCREEN, handleScreenEvent);
        stage.addEventListener(ScreenEvent.SHOW_LEVEL, handleScreenEvent);
    }


    private function handleScreenEvent(event:ScreenEvent):void
    {
        switch (event.type)
        {
            case ScreenEvent.SHOW_WELCOME_SCREEN:
            {
                this.showWelcomeScreen()
                break;
            }
            case ScreenEvent.SHOW_LEVEL:
            {
                // event.data contains level number
                this.startLevel(event.data);
                break;
            }
            default:
            {
                trace("Main.handleScreenEvent :: Cannot find event.type '" + event.type + "'.");
                break;
            }
        }
    }

    private function showWelcomeScreen():void
    {
        trace("show WelcomeScreen")
        //some private code in here
    }

    private function startLevel(level:int):void 
    {
        trace("start level: " + level)
        //some other private code here
    }
}

这是自定义事件类的外观( ScreenEvent.as )。请注意,它有一个名为 data 的可选参数。您可以将任何值(对象,数字,字符串等)传递给此。对于尽可能清楚的示例,我为这两个操作使用了一个事件类,您还可以选择为具有更详细参数的其他操作创建更具体的自定义事件,您可以使用 ScreenEvent 这样的名称, LevelEvent PlayerEvent GameEvent 等等。

在类的顶部定义了(静态常量)类型。一个事件应该只有吸气剂。

package 
{
    import flash.events.Event;

    public class ScreenEvent extends Event
    {
        public static const SHOW_WELCOME_SCREEN:String = "ScreenEvent.showWelcomeScreen";
        // event.data contains level number
        public static const SHOW_LEVEL:String = "ScreenEvent.showLevel";

        private var _data:String;

        public function ScreenEvent(type:String, data:String):void 
        { 
            super(type);
            this._data = data;
        }

        public function get data():String
        {
            return this._data;
        }

        override public function clone():Event 
        { 
            return new ScreenEvent(this.type, this._data);
        }
    }
}

..您的代码中的任何地方都可以将事件发送到舞台。

// dispatch event to Main (stage). Should show welcome screen in our case
stage.dispatchEvent(new ScreenEvent(ScreenEvent.SHOW_WELCOME_SCREEN));

// show level 2
stage.dispatchEvent(new ScreenEvent(ScreenEvent.SHOW_LEVEL, 2));

我知道,它的代码更多,起初看起来更难,但如果项目增长,它将会有很大帮助。与事件的区别在于'这可能发生,当它发生时,执行此操作'而不是'在此处执行此操作,在那里执行此操作 优点是,如果你删除Main类中的事件监听器,任何东西都不会中断(松散耦合)。这使得它更容易维护,它节省了单例,并且您可以扩展Main类 if

答案 1 :(得分:1)

我想你写了

Main.startLevelOne();

而不是

Main.instance.startLevelOne();

答案 2 :(得分:1)

嗯。鉴于您的代码,只有一个严肃的问题 - PerwollGame是什么?你有public static var instance:PerwollGame;并为它分配一个Main类型的对象。也许PerwollGame有一个带有不同签名的startLevelOne()函数,它会掩盖你在Main类中的功能。另外,回答你的其他人也是对的,你不应该在你的代码中使用嵌套函数,真的把你的听众放在内联声明中。

答案 3 :(得分:0)

根据您的编码风格和报告的错误判断,我会假设您这样做了。

public static function startLevelOne():void

静态方法和实例化对象之间存在一条细线。

也绝不使用嵌套函数

public class LevelBrief extends MovieClip
{

    public function LevelBrief()
    {
        // constructor code
        startBut.addEventListener('click', onMyClick )
    }

    public functiononMyClick (e:Event) {
            Main.instance.startLevelOne();
        });
    }
}

答案 4 :(得分:0)

我假设您注册监听器时Main.instance尚未分配。 您是否尝试在此处跟踪主实例?

public function LevelBrief()
{
    // constructor code
    startBut.addEventListener('click', function() {
        Main.instance.startLevelOne();
    });
    trace(Main.instance); // I assume Main.instance is null
}

如果你在LevelBrief中的另一个方法中添加监听器如下:

public function registerListeners():void{
        trace("Main.instance == null? -> " + (Main.instance == null)); //not null here if called later.
        startBut.addEventListener('click', function() {
        Main.instance.startLevelOne();
        });
    }