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
不同,它将引发相同的错误。既然你隐藏了你的代码,我不能做那么多!不,这不重要