开发者问题收集

我在计时器事件中不断收到“ArgumentError:错误 #2025:提供的 DisplayObject 必须是调用者的子对象”

2015-05-28
345

我试图从舞台上移除此物品,但一直出现此错误。代码似乎有效,对象已移除,但游戏似乎有点问题。

以下是完整错误:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/removeChild() at JumpingGame/onTick2()[E:\Folder\Folder\Folder\Folder\JumpingGame.as:95] at flash.utils::Timer/_timerDispatch() at flash.utils::Timer/tick()

错误指向:

  • removeChild(enemy)
  • removeChild(leg);
  • removeChild(life);

我还得到:

TypeError: Error #1009: Cannot access a property or method of a null object reference

在此行上 theLives.text = liveLives.toString();

以下是我的代码:

    package 
{
    import flash.display.MovieClip;
    import flash.utils.Timer;
    import flash.events.TimerEvent;

    public class JumpingGame extends MovieClip 
    {
        public var army:Array;
        public var powerups:Array;
        public var pluslives:Array;

        public var newDoodle:doodle;

        public var enemyTimer:Timer;
        public var legTimer:Timer;
        public var lifeTimer:Timer; 

        public function JumpingGame() 
        {

            enemyTimer = new Timer( 40 );
            enemyTimer.addEventListener( TimerEvent.TIMER, onTick );
            enemyTimer.start();

            legTimer = new Timer( 20 );
            legTimer.addEventListener( TimerEvent.TIMER, onTick2 );
            legTimer.start();

            lifeTimer = new Timer( 30 );
            lifeTimer.addEventListener( TimerEvent.TIMER, onTick3 );
            lifeTimer.start();

            army = new Array();
            var newEnemy = new Enemy( 100, -15 );
            army.push( newEnemy );
            addChild( newEnemy );

            powerups = new Array();
            var newLeg = new Leg( 300, -15 );
            powerups.push( newLeg );
            addChild( newLeg );

            pluslives = new Array();
            var newLife = new Plus1( 300, -15 );
            pluslives.push( newLife );
            addChild( newLife );

            newDoodle = new doodle();
            addChild( newDoodle );
            newDoodle.y = stage.stageHeight - 50;
            newDoodle.x = stage.stageWidth / 2;
        }

        public function onTick( timerEvent:TimerEvent ):void
        {
            if (Math.random() <0.005 )
            {
                var randomX:Number = Math.random() * 320;
                var newEnemy:Enemy = new Enemy( randomX, -15 );
                army.push( newEnemy );
                addChild( newEnemy );
            }

            for each ( var enemy:Enemy in army )
            {
                enemy.moveDownABit();
                if (newDoodle.hitTestObject( enemy ) )
                {
                    //gotoAndPlay ("Game Over");
                    removeChild(enemy);
                    liveLives -= 1;
                    theLives.text = liveLives.toString();

                }
            }
        }

        public function onTick2( timerEvent:TimerEvent ):void
        {
            if (Math.random() <0.008 )
            {
                var randomX2:Number = Math.random() * 320;
                var newLeg:Leg = new Leg( randomX2, -15 );
                powerups.push( newLeg );
                addChild( newLeg );
            }

            for each ( var leg:Leg in powerups )
            {
                leg.moveDownABit2();
                if (newDoodle.hitTestObject( leg ) )
                {
                    //gotoAndPlay ("Game Over");
                    removeChild(leg);
                    liveScore += 2000;
                    theScore.text = liveScore.toString();
                }
            }

        }

        public function onTick3( timerEvent:TimerEvent ):void
        {
            if (Math.random() <0.001 )
            {
                var randomX3:Number = Math.random() * 320;
                var newLife:Plus1 = new Plus1( randomX3, -15 );
                pluslives.push( newLife );
                addChild( newLife );
            }

            for each ( var life:Plus1 in pluslives )
            {
                life.moveDownABit3();
                if (newDoodle.hitTestObject( life ) )
                {
                    //gotoAndPlay ("Game Over");
                    removeChild(life);
                    liveLives += 1;
                    theLives.text = liveLives.toString();

                }
            }

        }
    }
}
3个回答

尝试使用:

enemy.parent.removeChild(enemy)
leg.parent.removeChild(leg);
life.parent.removeChild(life);

并且没有 liveLives 变量,或者舞台上的 theLives 文本字段拼写错误。

Antizam
2015-05-28

您遇到的问题是由于从显示列表中删除对象而没有从存储它们的数据结构中删除它们而导致的。

查看代码中的这段摘录: 假设 powerups 只有一个元素,并且 hitTestObject 返回 true。该对象从显示中删除。

for each ( var leg:Leg in powerups )
{
    if (newDoodle.hitTestObject( leg ) )
    {
         removeChild(leg);

代码第二次执行。该对象 仍然 在数组中。 hitTestObject 仍然 返回 true。 无法 从显示中删除对象,因为在第一次执行函数时它已被删除。

您有两个数据结构:显示列表和数组,它们不同步。

要解决此问题,请从数组中删除对象,而不仅仅是显示列表:

  1. 使用 indexOf()
  2. 找到要删除的对象的索引
  3. 使用 splice()
  4. 删除该索引处的元素
null
2015-05-28

在这种情况下,您不应使用 3 个数组来存储子对象。简单来说,您创建 3 个空影片剪辑并向其中添加子对象。之后,在命中测试时删除它们。

类似这样的内容:

    public function onTick( timerEvent:TimerEvent ):void
    {
        if (Math.random() <0.005 )
        {
            var randomX:Number = Math.random() * 320;
            var newEnemy:Enemy = new Enemy( randomX, -15 );
            armyContainer.addChild( newEnemy );
        }

        var childs:Array = [];
        for (var i:int = 0; i<armyContainer.numChildren; i++) {
            var enemy:Enemy = armyContainer.getChildAt(i) as Enemy;
            enemy.moveDownABit();
            if (newDoodle.hitTestObject( enemy ) )
            {
                //gotoAndPlay ("Game Over");
                //removeChild(enemy);
                childs.push(enemy);
                liveLives -= 1;
                theLives.text = liveLives.toString();

            }
        }

        for each ( var child:Enemy in childs )
        {
            armyContainer.removeChild(child);
        }
    }
Tram Nguyen
2015-06-02