0

そのため、提供された DisplayObject は呼び出し元の子でなければならないというエラーが表示されます。'Play'何が起こるかというと、ボタンをクリックすると関数が呼び出さstartGameれ、メニューが削除されてゲームが表示されるという点で、私のゲームは初めて動作しますが、ゲームの最後にplayAgainBtnをクリックすると、単純にゲームをもう一度プレイしたり再起動したりするのではなく、ゲーム、私はこのエラーが発生します:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/removeChild()

具体的には次の行を指しています。

menuLayer.removeChild(mainMenu);

コードは次のとおりです。

package  {
    import flash.display.MovieClip;
    import flash.display.LoaderInfo;
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import flash.ui.Mouse;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.text.TextFormat;
    import flash.text.TextField;
    import flash.text.AntiAliasType;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.net.URLLoader;
    import flash.system.LoaderContext;
    import flash.display.Sprite;
    import flash.net.Socket;
    import caurina.transitions.Tweener;
    import flash.text.Font;

    public class Main extends MovieClip {

    public static var backgroundLayer:Sprite = new Sprite;
    public static var gameLayer:Sprite = new Sprite;
    public static var interfaceLayer:Sprite = new Sprite;
    public static var endGameLayer:Sprite = new Sprite;
    public static var menuLayer:Sprite = new Sprite;
    public static var gameOverLayer:Sprite = new Sprite;
    public static var howToLayer:Sprite = new Sprite;
    public static var scoresLayer:Sprite = new Sprite;
    public static var aboutLayer:Sprite = new Sprite;

    public var mainMenu:menuMain = new menuMain;
    public var gameEnd:endGame = new endGame;
    public var howtoPlay:howToPlay = new howToPlay;
    public var gameAbout:aboutGame = new aboutGame;
    public var intro:IntroSound = new IntroSound();
    public var soundControl:SoundChannel = new SoundChannel();

    public var gameTime:int;
    public var levelDuration:int;

    public var crosshair:crosshair_mc;
    static var score:Number;

    var enemyShipTimer:Timer;
    var enemyShipTimerMed:Timer;
    var enemyShipTimerSmall:Timer;

    static var scoreHeader:TextField = new TextField();
    static var scoreText:TextField = new TextField();
    static var timeHeader:TextField = new TextField();
    static var timeText:TextField = new TextField();

    static var scoreFormat = new TextFormat("Arial Rounded MT Bold", 20, 0xFFFFFF);
    public var gameOverscoreFormat = new TextFormat("Arial Rounded MT Bold", 32, 0xFFFFFF);

   public function Main()
   {
        addChild(gameLayer);
        addChild(backgroundLayer);
        addChild(interfaceLayer);
        addChild(menuLayer);

        menuLayer.addChild(mainMenu);
        interfaceLayer.addChild(howtoPlay);
        interfaceLayer.addChild(gameEnd);
        interfaceLayer.addChild(gameAbout);
        soundControl = intro.play(0, 100);
        addMenuListeners();
   }

   public function menuReturn(e:Event)
   {

        addChild(gameLayer);
        addChild(backgroundLayer);
        addChild(interfaceLayer);
        addChild(menuLayer);

        menuLayer.addChild(mainMenu);
        interfaceLayer.addChild(howtoPlay);
        interfaceLayer.addChild(gameEnd);
        interfaceLayer.addChild(gameAbout);
   }

   public function showAbout(e:Event)
   {
      menuLayer.removeChild(mainMenu);
      interfaceLayer.addChild(gameAbout);
   }

   public function startGame(e:Event)
   {
        removeMenuListeners();
        soundControl.stop();
        interfaceLayer.removeChild(howtoPlay);
        interfaceLayer.removeChild(gameAbout);
        interfaceLayer.removeChild(gameEnd);
        menuLayer.removeChild(mainMenu);

        levelDuration = 30;
        gameTime = levelDuration;
        var gameTimer:Timer = new Timer(1000,levelDuration);
        gameTimer.addEventListener(TimerEvent.TIMER, updateTime);
        gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeExpired)
        gameTimer.start();

        scoreHeader = new TextField();
        scoreHeader.text = String("Score: ");
        interfaceLayer.addChild(scoreHeader);
        scoreHeader.x = 5;
        scoreHeader.selectable = false;
        scoreHeader.embedFonts = true;
        scoreHeader.antiAliasType = AntiAliasType.ADVANCED;

        scoreText = new TextField();
        scoreText.text = String("0");
        interfaceLayer.addChild(scoreText);
        scoreText.x = 75;
        scoreText.y = 0;
        scoreText.selectable = false;
        scoreText.embedFonts = true;
        scoreText.antiAliasType = AntiAliasType.ADVANCED;

        timeHeader = new TextField();
        timeHeader.text = String("Time: ");
        interfaceLayer.addChild(timeHeader);
        timeHeader.x = 500;
        timeHeader.y = 0;
        timeHeader.selectable = false;
        timeHeader.embedFonts = true;
        timeHeader.antiAliasType = AntiAliasType.ADVANCED;

        timeText = new TextField();
        timeText.text = gameTime.toString();
        interfaceLayer.addChild(timeText);
        timeText.x = 558;
        timeText.y = 0;
        timeText.selectable = false;
        timeText.embedFonts = true;
        timeText.antiAliasType = AntiAliasType.ADVANCED;

        scoreHeader.setTextFormat(scoreFormat);
        scoreText.setTextFormat(scoreFormat);
        timeHeader.setTextFormat(scoreFormat);
        timeText.setTextFormat(scoreFormat);

        var timeScorebg:Sprite = new Sprite();
        backgroundLayer.addChild(timeScorebg);
        timeScorebg.graphics.beginFill(0x333333);
        timeScorebg.graphics.drawRect(0,0,600,30);
        timeScorebg.graphics.endFill();
        timeScorebg.y = 0;

        enemyShipTimer = new Timer(2000);
        enemyShipTimer.addEventListener("timer", sendEnemy);
        enemyShipTimer.start();

        enemyShipTimerMed = new Timer(2500);
        enemyShipTimerMed.addEventListener("timer", sendEnemyMed);
        enemyShipTimerMed.start();

        enemyShipTimerSmall = new Timer(2750);
        enemyShipTimerSmall.addEventListener("timer", sendEnemySmall);
        enemyShipTimerSmall.start();

        crosshair = new crosshair_mc();
        gameLayer.addChild(crosshair);

        crosshair.mouseEnabled = crosshair.mouseChildren = false;

        Mouse.hide();

        gameLayer.addEventListener(Event.ENTER_FRAME, moveCursor);
        resetScore();
    }

    function addMenuListeners():void
    {
        mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
        mainMenu.howToPlayBtn.addEventListener(MouseEvent.CLICK, showInstructions);
        mainMenu.aboutBtn.addEventListener(MouseEvent.CLICK, showAbout);
        howtoPlay.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
        gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, startGame);
        gameAbout.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
    }

    function removeMenuListeners():void
    {
        mainMenu.playBtn.removeEventListener(MouseEvent.CLICK, startGame);
        mainMenu.howToPlayBtn.removeEventListener(MouseEvent.CLICK, showInstructions);
        mainMenu.aboutBtn.removeEventListener(MouseEvent.CLICK, showAbout);
        howtoPlay.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
        gameEnd.playagainBtn.removeEventListener(MouseEvent.CLICK, startGame);
        gameAbout.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
    }

    public function showInstructions(e:Event)
    {
        menuLayer.removeChild(mainMenu);
        interfaceLayer.addChild(howtoPlay);
    }

    function sendEnemy(e:Event)
    {
        var enemy = new EnemyShip();
        gameLayer.addChild(enemy);
        gameLayer.addChild(crosshair);
    }

    function sendEnemyMed(e:Event)
    {
        var enemymed = new EnemyShipMed();
        gameLayer.addChild(enemymed);
        gameLayer.addChild(crosshair);
    }

    function sendEnemySmall(e:Event)
    {
        var enemysmall = new EnemyShipSmall();
        gameLayer.addChild(enemysmall);
        gameLayer.addChild(crosshair);
    }

    static function updateScore(points)
    {
        score += points;
        scoreText.text = String(score);
        scoreHeader.setTextFormat(scoreFormat);
        scoreText.setTextFormat(scoreFormat);
    }

    static function resetScore()
    {
        score = 0;
        scoreText.text = String(score);
        scoreText.setTextFormat(scoreFormat);
    }

    function updateTime(e:TimerEvent):void
    {
        gameTime--;
        timeText.defaultTextFormat = scoreFormat;
        timeText.text = String(gameTime);
    }

    function timeExpired(e:TimerEvent):void
    {
        var gameTimer:Timer = e.target as Timer;
        gameTimer.removeEventListener(TimerEvent.TIMER, updateTime)
        gameTimer.removeEventListener(TimerEvent.TIMER, timeExpired)

        interfaceLayer.addChild(gameEnd);

        var thisFont:Font = new myFont();
        var myFormat:TextFormat = new TextFormat();
        myFormat.font = thisFont.fontName;

        scoreText = new TextField();
        scoreText.defaultTextFormat = myFormat;
        scoreText.text = String(score);
        interfaceLayer.addChild(scoreText);
        scoreText.x = 278;
        scoreText.y = 180;
        scoreText.selectable = false;
        scoreText.embedFonts = true;
        scoreText.antiAliasType = AntiAliasType.ADVANCED;
        scoreText.setTextFormat(gameOverscoreFormat);

        Mouse.show();
        removeChild(gameLayer);
        addMenuListeners();
    }

    function moveCursor(event:Event) 
    {
      crosshair.x=mouseX;
      crosshair.y=mouseY;
    }
    }
  }

これを修正する方法がよくわからないので、アドバイスや解決策は大歓迎です。エラーが発生せずに意図したとおりに動作させることはできません。

ありがとう。

4

6 に答える 6

1

問題はmenuLayer.removeChild(mainMenu);、2回目のプレイスルーで呼び出していることで、すでに一度削除したためにエラーがスローされていると思います。最も簡単な解決策は、削除しようとする前に、menuLayer に mainMenu が含まれていることを確認することです。

if(menuLayer contains mainMenu)
    menuLayer.removeChild(mainMenu);

(私は現在 IDE にアクセスできないことに注意してください。しかし、これでうまくいくと思います)

より堅牢な解決策は、再生ボタンが から削除されたメイン メニューからクリックされたときに別のメソッドを呼び出してから呼び出すことですmainMenu( menuLayerasstartGameは直接playAgain呼び出しstartGameます)。

編集 OK、あなたの言いたいことがわかります。おそらく、代わりに次のようなものがあります。

mainMenu.playBtn.addEventListener(MouseEvent.CLICK, playGame);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, playGameAgain);
...
public function playGame(e:Event)
{
    menuLayer.removeChild(mainMenu);
    startGame();
}
...
public function playGameAgain(e:Event)
{
    startGame();
}
...
public function startGame()
于 2013-05-15T14:51:52.253 に答える
0

ゲームオーバーがどのように処理されるかを確認せずにこれを確認することはできませんが、ゲームがプレイされるたびにイベントリスナーを削除していないことが潜在的な問題だと思います. したがって、メイン メニューに戻って再度追加すると、playAgainBtn のリスナーが 2 つになります。

したがって、ゲームを終了して playAgainBtn をクリックすると、startGame が 2 回呼び出されます。したがって、最初は問題なく削除され、2 回目は削除するものが何もありません。現在の設計では、すべてのイベント リスナーにこの問題が存在する可能性があります。

この場合、メニューが削除されたときにイベント リスナーを削除するだけです。

メニューをアクティブにするときはいつでもリスナーを追加し、それを非表示にするときはいつでも削除することをお勧めします。おそらく、addMenuListeners と removeMenuListeners の 2 つのメソッドがあります。

これら 2 つの関数を作成し、必要に応じて使用できます。

   function addMenuListeners():void
   {
        mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
        mainMenu.howToPlayBtn.addEventListener(MouseEvent.CLICK, showInstructions);
        mainMenu.aboutBtn.addEventListener(MouseEvent.CLICK, showAbout);
        howtoPlay.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
        gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, startGame);
        gameAbout.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
   }

function removeMenuListeners():void
{
        mainMenu.playBtn.removeEventListener(MouseEvent.CLICK, startGame);
        mainMenu.howToPlayBtn.removeEventListener(MouseEvent.CLICK, showInstructions);
        mainMenu.aboutBtn.removeEventListener(MouseEvent.CLICK, showAbout);
        howtoPlay.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
        gameEnd.playagainBtn.removeEventListener(MouseEvent.CLICK, startGame);
        gameAbout.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
}

使用していないイベント リスナーを常に削除するという規則に従うと、この問題を回避できます。

于 2013-05-15T17:16:23.290 に答える
0

コードが機能しない理由はわかりませんが、心配する必要はありません。試してみてください:

 MovieClip(menuLayer.parent).removeChild(menuLayer);
于 2013-05-15T14:27:56.900 に答える