Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 公共功能访问失败_Actionscript 3_Flash - Fatal编程技术网

Actionscript 3 公共功能访问失败

Actionscript 3 公共功能访问失败,actionscript-3,flash,Actionscript 3,Flash,在这种情况下,我在主类中声明一个函数,如下所示: public class Main extends MovieClip { public static var instance:Main; public function Main() { // constructor code welcomeScreen(); instance = this; } public final function welc

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

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();
});
不知何故,在另一个类中,我尝试对“StartLevel One”使用相同的语句,但它似乎不起作用,并给出了一个衰减错误:

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

我已经在这里粘贴了主定义的完整代码

另一个类也可以在这里找到

更新#3

即使这个问题通过解决方法解决了,我仍然不明白问题出在哪里。

我想是你写的

Main.startLevelOne();
而不是

Main.instance.startLevelOne();
我想是你写的

Main.startLevelOne();
而不是

Main.instance.startLevelOne();

从您的编码风格和报告的错误判断,我认为您这样做了

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();
        });
    }
}

从您的编码风格和报告的错误判断,我认为您这样做了

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();
        });
    }
}

嗯,考虑到你的代码,只有一个严肃的问题——PerwollGame是什么?您有
公共静态var实例:PerwollGame并为其指定一个Main类型的对象。也许PerwollGame有一个带有不同签名的
startLevel()。另外,其他回答您的人也是对的,您不应该在代码中使用嵌套函数,而应该将您的侦听器从内联声明中排除。

嗯。考虑到您的代码,只有一个严肃的问题-PerwollGame是什么?您有
公共静态var实例:PerwollGame并为其指定一个Main类型的对象。也许PerwollGame有一个带有不同签名的
startLevel()。另外,回答您的其他人也是对的,您永远不应该在代码中使用嵌套函数,而应该将您的侦听器从内联声明中删除。

我假定,当您注册侦听器时,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();
        });
    }

我假设在注册listener时,尚未分配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();
        });
    }

我建议离开静态实例(单例),并基于工作事件。现在将所有函数公开,这是不可取的。使用自定义事件并不难。请看,这是您的主要类的外观:

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等名称

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

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));
我知道,这是一个多一点的代码,它看起来更难在一开始,但如果该项目的增长,它将帮助很多。事件的区别在于“这可能发生,当它发生时,做这个”而不是“在这里做这个,在那里做那个”
其优点是,如果删除主类中的事件侦听器,则不会有任何内容中断(松散耦合)。这使得它更易于维护,它节省了一个单例,并且如果需要,您可以扩展主类

我建议离开静态实例(单例),并基于工作事件。现在将所有函数公开,这是不可取的。使用自定义事件并不难。请看,这是您的主要类的外观:

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等名称

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

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));
我知道,这是一个多一点的代码,它看起来更难在一开始,但如果该项目的增长,它将帮助很多。事件的区别在于“这可能发生,当它发生时,做这个”而不是“在这里做这个,在那里做那个”
其优点是,如果删除主类中的事件侦听器,则不会有任何内容中断(松散耦合)。这使得它更易于维护,它节省了一个单例,并且如果需要,您可以扩展主类

您是否可以附加有问题的代码块(使用
startevelone
调用)?
Main
是否实现了一个声明
startevelone()
的接口?因为上面的代码在使用Flash Builder编译时运行良好…您所说的“实现接口”是什么意思?类似于
public class Main扩展MovieClip实现GameController
。在我的示例中,如果
GameController
声明的
startevelone()
签名与
Main
不同,它将引发相同的错误。既然你隐藏了你的代码,我不能做那么多!不,这不重要