Actionscript 3 按钮只工作一次
我有一个问题,我的按钮只工作一次。该按钮触发一个自定义事件。自定义事件激发,DocumentClass上的侦听器第一次拾取该事件,但此后任何时候都不响应 复制 ,然后单击“开始游戏”,然后单击右上角的菜单按钮,然后单击主菜单,然后单击“开始游戏”,然后单击右上角的菜单按钮,请注意,您不能再次单击主菜单。这是我的问题。它应该继续发挥作用 DocumentClass添加子openScreen。openScreen为DocumentClass触发事件以添加子playScreen并删除openScreen。单击playscreen上的菜单按钮时,playscreen会添加子菜单屏幕**单击主菜单按钮时,会触发DocumentClass侦听的事件。触发的功能将删除播放屏幕并添加打开的屏幕。当**步骤执行时,此系列事件仅在挂断前完全工作一次 文档类Actionscript 3 按钮只工作一次,actionscript-3,flash,air,Actionscript 3,Flash,Air,我有一个问题,我的按钮只工作一次。该按钮触发一个自定义事件。自定义事件激发,DocumentClass上的侦听器第一次拾取该事件,但此后任何时候都不响应 复制 ,然后单击“开始游戏”,然后单击右上角的菜单按钮,然后单击主菜单,然后单击“开始游戏”,然后单击右上角的菜单按钮,请注意,您不能再次单击主菜单。这是我的问题。它应该继续发挥作用 DocumentClass添加子openScreen。openScreen为DocumentClass触发事件以添加子playScreen并删除openScree
public class DocumentClass extends MovieClip
{
public var playScreen:PlayScreen = new PlayScreen();
public var openScreen:OpenScreen = new OpenScreen();
public var started:Boolean = false;
public function DocumentClass()
{
openScreen.addEventListener( GameEvent.STAR, OnPlayClick);
playScreen.addEventListener( GameEvent.NG, NewGame);
playScreen.menuScreen.addEventListener( GameEvent.NG, NewGame, true, 0, true);
playScreen.menuScreen.addEventListener( GameEvent.MM, onMain);
addChild(openScreen)
}
public function OnPlayClick(gameEvent:GameEvent):void{
trace("start")
addChildAt(playScreen,0)
var tweenX:Tween = new Tween(openScreen, "x", None.easeIn, 0, -480, .5, true);
tweenX.addEventListener(TweenEvent.MOTION_FINISH, onTweenDone);
}
public function NewGame(gameEvent:GameEvent):void{
removeChild(playScreen)
playScreen = new PlayScreen();
addChild(playScreen)
playScreen.begin()
}
public function onMain(gameEvent:GameEvent):void{
playScreen.removeChild(playScreen.menuScreen)
this.removeChild(playScreen)
//openScreen = new OpenScreen();
openScreen.x = 0
addChild(openScreen)
playScreen = new PlayScreen();
菜单屏幕
公共类MenuScreen扩展了MovieClip
{
露天屏幕
public class OpenScreen extends MovieClip
{
public var hs:String
public function OpenScreen()
{
startButton.buttonMode = true
startButton.addEventListener( MouseEvent.CLICK, OnStartClick );
exitButton.buttonMode = true
exitButton.addEventListener( MouseEvent.CLICK, OnExitClick );
//NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, onSystemKey);
readObject()
highScoreText.text = String(hs)
trace(highScoreText.text)
startButton.AnswerText.text = "Start"
//restartButton.AnswerText.text = "Restart"
//mainButton.AnswerText.text = "Main Menu"
exitButton.AnswerText.text = "Exit"
}
public function OnStartClick(myEvent:MouseEvent):void{
trace(this.hasEventListener( GameEvent.STAR ))
this.dispatchEvent( new GameEvent( GameEvent.STAR ))
}
public function OnExitClick(myEvent:MouseEvent):void{
//NativeApplication.nativeApplication.exit();
}
protected function onSystemKey(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.BACK)
{
//NativeApplication.nativeApplication.exit();
}
else if(e.keyCode == Keyboard.HOME)
{
//handle the button press here.
}
else if(e.keyCode == Keyboard.MENU)
{
}
}
原因似乎是,在你的
onMain
方法中,你从舞台上移除,然后创建一个全新的播放屏幕实例。因此,你的侦听器连接到旧的实例。这也会造成内存泄漏
public function onMain(gameEvent:GameEvent):void{
playScreen.removeChild(playScreen.menuScreen)
this.removeChild(playScreen)
//openScreen = new OpenScreen();
openScreen.x = 0
addChild(openScreen)
playScreen = new PlayScreen(); //RIGHT HERE - this is creating a whole new play screen, your listeners are attached to the old one.
}
应该是这样的:(取出构造函数中的play screen代码,在声明时不要实例化它)
这是一个合理的问题,这样做可以解决我的按钮不工作的问题。新的游戏屏幕是我制作新游戏的方式,因为所有的游戏机制都包含在游戏屏幕中。有没有更好的方式将孩子重置为调用前的状态?可能是一种更有效的方式,但这取决于如果应用程序的性能足够,则清除并重新实例化没有什么错——只需确保没有任何东西将上一个播放屏幕保留在内存中(如事件侦听器)
public function onMain(gameEvent:GameEvent):void{
playScreen.removeChild(playScreen.menuScreen)
this.removeChild(playScreen)
//openScreen = new OpenScreen();
openScreen.x = 0
addChild(openScreen)
playScreen = new PlayScreen(); //RIGHT HERE - this is creating a whole new play screen, your listeners are attached to the old one.
}
//Create a function that kill your current play screen
public function clearPlayScreen():void {
if(!playScreen) return; //don't do anything if there isn't a play screen
playScreen.removeChild(playScreen.menuScreen)
this.removeChild(playScreen);
//remove your listeners so the old play screen can be garbage collected - other they will all stay in memory causing a memory leak
playScreen.removeEventListener( GameEvent.NG, NewGame);
playScreen.menuScreen.removeEventListener( GameEvent.NG, NewGame, true);
playScreen.menuScreen.removeEventListener( GameEvent.MM, onMain);
playScreen = null;
}
public function NewGame(gameEvent:GameEvent):void{
clearPlayScreen(); //kill the old play screen if it exists
playScreen = new PlayScreen();
addChild(playScreen);
//add the listeners to the new play screen
playScreen.addEventListener( GameEvent.NG, NewGame);
playScreen.menuScreen.addEventListener( GameEvent.NG, NewGame, true, 0, true);
playScreen.menuScreen.addEventListener( GameEvent.MM, onMain);
playScreen.begin();
}
public function onMain(gameEvent:GameEvent):void{
clearPlayScreen();
//openScreen = new OpenScreen();
openScreen.x = 0;
addChild(openScreen);
}