-1

私はフラッシュと as3 プログラミングが初めてで、これが私の最初のプロジェクトです。このようなプロジェクトでエラーが見つかりました

TypeError: エラー #1009: null オブジェクト参照のプロパティまたはメソッドにアクセスできません。src.char::Enemy/Remove() で src.screen::Gameplay/Collision() で src.screen::Gameplay/Routine() で

ゲームプレイ上に関数 Remove() がないためにエラーが発生すると思いますが、それが正しいかどうかはわかりません。これが敵です。

import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;

public class Enemy extends MovieClip {

    private var timer:Timer = new Timer(25);

    public function Enemy(xPos:Number, yPos:Number) {
        x = xPos;
        y = yPos;
        timer.addEventListener(TimerEvent.TIMER, MoveDown);
        timer.start();
    }

    private function MoveDown(e:TimerEvent):void {
        y += 3;
        if (y>400) {
            Remove();
        }
    }

    public function Remove():void {
        timer.stop();
        timer.removeEventListener(TimerEvent.TIMER, MoveDown);
        parent.removeChild(this);
    }

}

ここにgameplay.asがあります

    public class Gameplay extends MovieClip {

    private var timer:Timer = new Timer(500);
    private var player:Player;

    public function Gameplay() {
        addEventListener(Event.ADDED_TO_STAGE, InitKeyboard);
        addEventListener(Event.ENTER_FRAME, Routine);
        gameplayBack.addEventListener(MouseEvent.CLICK, GoToMap);
        timer.addEventListener(TimerEvent.TIMER, OnTick);
        timer.start();
        InitPlayer();
        InitLifePoint();
    }

    private function InitLifePoint():void {
        lifePoint.gotoAndStop(1);           
    }

    private function Routine(e:Event):void {
        Collision();
    }

    private function Collision():void {
        for (var i:int = 0; i < enemies.length; i++ ) {
            if (player.hitTestObject(enemies[i])) {
                PlayerHit();
                enemies[i].Remove();
                return;
            }else {
                for (var j:int = 0; j < bullets.length; j++ ) {
                    if (bullets[j].hitTestObject(enemies[i])) {
                        layerParticle.addChild(new Blast(bullets[j].x, bullets[j].y));
                        layerParticle.addChild(new Smoke(bullets[j].x, bullets[j].y));
                        bullets[j].Remove();
                        enemies[i].Remove();
                        scorePlay.text = int(scorePlay.text) + 10 + "";
                        trace(scorePlay.text);
                        return;
                    }
                }
            }
        }
    }


    private var life:int = 1000;
    private var currentLife:int = 1000;
    private function PlayerHit():void {
        currentLife -= 100;
        if (currentLife <= 0) {
            lifePoint.gotoAndStop(100);
            GameOver();
        }else {
            lifePoint.gotoAndStop(100 - currentLife / life * 100);
        }
    }

    private var result:Result = new Result();
    private function GameOver():void {
        result.youWin.alpha = 0;
        result.ok.addEventListener(MouseEvent.CLICK, GoToMap);
        result.x = 0;
        result.y = 0;
        addChild(result);
    }

    private function InitKeyboard(e:Event):void {
        removeEventListener(Event.ADDED_TO_STAGE, InitKeyboard);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
    }

    private function KeyDown(e:KeyboardEvent):void {
        switch(e.keyCode) {
            case Keyboard.LEFT: MoveLeft(); break;
            case Keyboard.RIGHT: MoveRight(); break;
            case Keyboard.SPACE: Fire(); break;
        }
    }

    private var bullets:Array = new Array();
    private function Fire():void {
        var bullet:Bullet = new Bullet(player.x, player.y);
        bullet.scaleX = 0.25;
        bullet.scaleY = 0.25;
        bullet.addEventListener(Event.REMOVED_FROM_STAGE, RemoveBulletArray);
        layerParticle.addChild(bullet);
        bullets.push(bullet);
    }

    private function RemoveBulletArray(e:Event):void {
        removeEventListener(Event.REMOVED_FROM_STAGE, RemoveBulletArray);
        var index:int = bullets.indexOf(Bullet(e.currentTarget), 0);
        bullets.splice(index, 1);
    }

    private function MoveRight():void {
        if (player.x < 550) {
            player.x += 5;
        }
    }

    private function MoveLeft():void {
        if (player.x > 0) {
            player.x -= 5;
        }
    }

    private function InitPlayer():void {
        player = new Player(550 * 0.5, 350);
        layerChar.addChild(player);
    }

    private function OnTick(e:TimerEvent):void {
        RandomEnemy();
    }

    private var enemies:Array = new Array();
    private function RandomEnemy():void {
        var enemy:Enemy = new Enemy(Math.random() * 550, 0);
        enemy.addEventListener(Event.REMOVED_FROM_STAGE, RemoveFromArray);
        layerChar.addChild(enemy);
        enemies.push(enemy);
    }

    private var remaining:int = 10;
    private function RemoveFromArray(e:Event):void {
        removeEventListener(Event.REMOVED_FROM_STAGE, RemoveFromArray);
        var index:int = enemies.indexOf(Enemy(e.currentTarget), 0);
        enemies.slice(index, 1);
        remaining--;
        if (remaining == 0) GameWin();
    }

    private function GameWin():void {
        result.youLose.alpha = 0;
        result.score.text = scorePlay.text;
        result.ok.addEventListener(MouseEvent.CLICK, GoToMap);
        result.x = 0;
        result.y = 0;
        addChild(result);
    }

    private function GoToMap(e:MouseEvent):void {
        dispatchEvent(new ScreenEvent(ScreenEvent.MAP));
    }

}
4

2 に答える 2

1

あなたの問題は、 Enemy.Remove() メソッド内の NPE (Null Pointer Exception/Error) です。

public function Remove():void {
    timer.stop();
    timer.removeEventListener(TimerEvent.TIMER, MoveDown);
    parent.removeChild(this);
}

あなたのtimerプロパティがnullであるか(あなたのコードを見て、私は疑問に思っています)、parentプロパティがそうです。

aMovieClipのプロパティは、あなたが追加されparentた場合は a で埋められ、追加されていない場合、このプロパティはです。DisplayObjectMovieClipnull

あなたの問題はおそらく、これを(親から)MovieClip複数回削除しているか、最初に追加せずに削除しようとしていることです。

これが問題であることを確認するには、次のように、最初にプロパティifをチェックするステートメントを追加します。parent

if(parent != null)
{
    parent.removeChild(this);
}

:
これにより、NPE の問題が解決する場合がありますが、原因が解決されないため、ますます不可解なバグが発生する可能性があります。
ロジックを再確認して、以前に追加した を削除していることMovieClip、または複数回削除していないことを確認してください。

于 2013-01-26T17:29:54.087 に答える
0

次のように観察すると、衝突関数の欠陥に気づきますか?

for (var i:int = 0; i < enemies.length; i++) {
            if (~) {
                ...
                enemies[i].Remove();
                ...
            } else {
                for (~) {
                    if (~) {
                        ...
                        enemies[i].Remove();
                        ...
                    }
                }
            }
        }

どうやら、2番目のforループでは、同じ敵オブジェクトを簡単に参照できます。

また、 Remove関数 を呼び出した後に問題が発生します。これを行うparent.removeChild(this);と、オブジェクトの親オブジェクトへの唯一の参照が削除されるためです。

次のいずれかを試すことができます。

  • クラス内の親オブジェクトへの参照を手動で保持します。
  • クラスに状態変数を保持して、それがディスプレイリストの一部であるかどうかを確認します。
  • enemies[i].Remove();コードを最も外側のループに移動します。
  • 可能であれば、オブジェクトをリサイクルしてください。特に、ムービークリップを(x、y)動かしているだけの場合は特にそうです。
于 2013-01-26T18:21:11.530 に答える