AS3 - removeEventListener(ADDED_TO_STAGE)
Posted
技术标签:
【中文标题】AS3 - removeEventListener(ADDED_TO_STAGE)【英文标题】: 【发布时间】:2012-11-08 18:21:53 【问题描述】:我在尝试删除 Event.ADD_TO_STAGE
时遇到了一些问题,基本上在我开发的这个游戏中,一旦生命小于或等于零,游戏将结束并切换到屏幕上的游戏,但是当我这样做时它会踢返回此错误。
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at States/changeState()
at AvoiderGame/onTick()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
然后变成..
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Enemy/StayOnScreen()
at AvoiderGame/onTick()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
我不完全确定为什么 - 谁能澄清它为什么会这样以及我该如何解决它?
package
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import com.freeactionscript.CollisionTest;
import flash.display.Stage;
public class AvoiderGame extends MovieClip
var theCallBackFunction:Function;
public static var enemyArray:Array;
public var enemy:Enemy
public var Background:gameBackground;
public var Lives:Number = 3;
public var avatar:Avatar;
public var gameTimer:Timer;
private var _collisionTest:CollisionTest;
private var numStars:int = 80;
private var fireTimer:Timer; //causes delay between fires
private var canFire:Boolean = true; //can you fire a laser
public function AvoiderGame(callBack)
this.addEventListener(Event.ADDED_TO_STAGE, init);
theCallBackFunction = callBack;
private function init(e:Event):void
Background = new gameBackground();
addChild(Background);
enemyArray = new Array();
avatar = new Avatar(stage);
addChild(avatar);
avatar.x = stage.stageWidth / 2;
avatar.y = stage.stageHeight / 2;
_collisionTest = new CollisionTest();
gameTimer = new Timer(25);
gameTimer.addEventListener(TimerEvent.TIMER, onTick);
gameTimer.start();
for (var i:int = 0; i < numStars; i++)
stage.addChildAt(new Star(stage), 1);
fireTimer = new Timer(1000, 1);
fireTimer.addEventListener(TimerEvent.TIMER, fireTimerHandler, false, 0, true);
fireTimer.start();
public function onTick(timerEvent:TimerEvent):void
if (Math.random() < 0.1)
trace('array length: ', AvoiderGame.enemyArray.length);
enemy = new Enemy(Math.round(1 + (500 - 1) * Math.random()), - 28, stage);
enemyArray.push(enemy);
addChild(enemy);
enemy.gotoAndStop("Enemy" + Math.round(1 + (5 - 1) * Math.random()))
canFire = avatar.UpdateAvatar(canFire);
if (canFire == false)
fireTimer.start();
avatar.StayOnScreen();
for each (var enemy:Enemy in enemyArray)
enemy.moveDown();
enemy.StayOnScreen();
if (_collisionTest.complex(enemy, avatar))
gameTimer.stop();
for each (var enemy:Enemy in enemyArray)
for(var i:int = 0; i < enemyArray.length; i++)
removeChild(enemyArray[i]);
enemyArray.splice(i, 1); //remove the i'th element as i'th element is the enemy containing the ID of hit enemy
Lives--;
trace('lives: ', Lives);
gameTimer.start();
if (Lives == 0)
removeEventListener(Event.ADDED_TO_STAGE, init)
theCallBackFunction(this, "over");
private function fireTimerHandler(e:TimerEvent) : void
//timer ran, we can fire again.
canFire = true;
【问题讨论】:
onTick 在哪里 - 你得到了错误?同样在 ADDED_TO_STAGE 的处理程序中,您应该取消注册它。 【参考方案1】://使用弱引用,以便在必要时处理监听器
this.addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
private function init(e:Event):void
//remove this now as we have added the object to the stage
this.removeEventListener(Event.ADDED_TO_STAGE, init);
//add a new listener that will fire when the object is removed from stage
this.addEventListener(Event.REMOVED_FROM_STAGE, reset, false, 0, true);
...
private function reset(e:Event):void
//this function is called when the object has been removed from the stage
this.removeEventListener(Event.REMOVED_FROM_STAGE, reset);
//now make sure all timers and stopped and nulled if required
//as well as all objects removed from stage and nulled if required. e.g.
fireTimer.stop();
fireTimer = null;
enemyArray = [];
enemyArray = null;
enemy
removeChild(Background);
Background = null;
removeChild(avatar);
avatar = null;
gameTimer.stop();
gameTimer = null;
_collisionTest = null;
//注意。您正在向舞台添加星星,但无法通过引用它们来移除它们。
for (var i:int = 0; i < numStars; i++)
stage.addChildAt(new Star(stage), 1);
//您可能希望将它们添加到数组中,以便删除它们。
var starArray = [];
for (var i:int = 0; i < numStars; i++)
var newStar:Star = new Star(stage);
stage.addChildAt(newStar, 1);
starArray.push(newStar);
然后删除它们:
for (var i:int = starArray.length; i > 0; i--)
stage.removeChild(starArray[starArray.length-1]);
starArray = [];
starArray = null;
【讨论】:
错误:错误 #2094:事件调度递归溢出。在 flash.display::DisplayObjectContainer/removeChild() 在 States/changeState() 在 AvoiderGame/reset() 在 flash.display::DisplayObjectContainer/removeChild() 在 States/changeState() 在 AvoiderGame/onTick() 在 flash.utils ::Timer/_timerDispatch() at flash.utils::Timer/tick() 这是自从我添加重置功能以来我一直得到的。 作为一般调试过程的一部分,如果错误不是很明显,请尝试将所有内容注释掉,然后取消注释并测试每一行代码块以查看错误何时出现。关于您的错误,请在执行任何其他操作之前尝试停止两个计时器。以上是关于AS3 - removeEventListener(ADDED_TO_STAGE)的主要内容,如果未能解决你的问题,请参考以下文章
Javascript里removeEventListener的必要
React document.removeEventListener 不起作用