2012-12-26 103 views
-1

我是flash中的初學者,目前出現問題。 我正在做一個遊戲,就像太空入侵者。 一開始就很好。 但是,當角色擊中敵人時, 會提示我錯誤。Actionscript 3.0 TypeError:錯誤#1009:無法訪問空對象引用的屬性或方法

TypeError:錯誤#1009:無法訪問空對象引用的屬性或方法。 在_fla :: MainTimeline/frame1126() 在flash.display使用::影片剪輯/ gotoAndStop() 在敵人/ eFrame()

我不知道什麼是錯的。 任何人都可以幫助我嗎?

這裏的來源爲我的時間表

stop(); 
//these booleans will check which keys are down 
var leftDown:Boolean = false; 
var upDown:Boolean = false; 
var rightDown:Boolean = false; 
var downDown:Boolean = false; 
//how fast the character will be able to go 
var mainSpeed:int = 5; 
//how much time before allowed to shoot again 
var cTime:int = 0; 
//the time it has to reach in order to be allowed to shoot (in frames) 
var cLimit:int = 12; 
//whether or not the user is allowed to shoot 
var shootAllow:Boolean = true; 
//how much time before another enemy is made 
var enemyTime:int = 0; 
//how much time needed to make an enemy 
//it should be more than the shooting rate 
//or else killing all of the enemies would 
//be impossible :O 
var enemyLimit:int = 16; 
//the player's score 
var score:int = 0; 
//this movieclip will hold all of the bullets 
var bulletContainer:MovieClip = new MovieClip(); 
addChild(bulletContainer); 
//whether or not the game is over 
var gameOver:Boolean = false; 

//adding a listener to mcMain that will move the character 
mcMain.addEventListener(Event.ENTER_FRAME, moveChar); 
function moveChar(event:Event):void{ 
    //checking if the key booleans are true then moving 
    //the character based on the keys 
    if(leftDown){ 
     mcMain.x -= mainSpeed; 
    } 
    if(upDown){ 
     mcMain.y -= mainSpeed; 
    } 
    if(rightDown){ 
     mcMain.x += mainSpeed; 
    } 
    if(downDown){ 
     mcMain.y += mainSpeed; 
    } 
    //keeping the main character within bounds 
    if(mcMain.x <= 0){ 
     mcMain.x += mainSpeed; 
    } 
    if(mcMain.y <= 0){ 
     mcMain.y += mainSpeed; 
    } 
    if(mcMain.x >= stage.stageWidth - mcMain.width){ 
     mcMain.x -= mainSpeed; 
    } 
    if(mcMain.y >= stage.stageHeight - mcMain.height){ 
     mcMain.y -= mainSpeed; 
    } 
    //Incrementing the cTime 

    //checking if cTime has reached the limit yet 
    if(cTime < cLimit){ 
     cTime ++; 
    } else { 
     //if it has, then allow the user to shoot 
     shootAllow = true; 
     //and reset cTime 
     cTime = 0; 
    } 

    //adding enemies to stage 
    if(enemyTime < enemyLimit){ 
     //if time hasn't reached the limit, then just increment 
     enemyTime ++; 
    } else { 
     //defining a variable which will hold the new enemy 
     var newEnemy = new Enemy(); 
     //making the enemy offstage when it is created 
     newEnemy.y = -1 * newEnemy.height; 
     //making the enemy's x coordinates random 
     //the "int" function will act the same as Math.floor but a bit faster 
     newEnemy.x = int(Math.random()*(stage.stageWidth - newEnemy.width)); 
     //then add the enemy to stage 
     addChild(newEnemy); 
     //and reset the enemyTime 
     enemyTime = 0; 
    } 
    //updating the score text 
    txtScore.text = 'Score: '+score; 
} 
//this listener will listen for down keystrokes 
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeysDown); 
function checkKeysDown(event:KeyboardEvent):void{ 
    //making the booleans true based on the keycode 
    //WASD Keys or arrow keys 
    if(event.keyCode == 37 || event.keyCode == 65){ 
     leftDown = true; 
    } 
    if(event.keyCode == 38 || event.keyCode == 87){ 
     upDown = true; 
    } 
    if(event.keyCode == 39 || event.keyCode == 68){ 
     rightDown = true; 
    } 
    if(event.keyCode == 40 || event.keyCode == 83){ 
     downDown = true; 
    } 

    //checking if the space bar is pressed and shooting is allowed 
    if(event.keyCode == 32 && shootAllow){ 
     //making it so the user can't shoot for a bit 
     shootAllow = false; 
     //declaring a variable to be a new Bullet 
     var newBullet:Bullet = new Bullet(); 
     //changing the bullet's coordinates 
     newBullet.x = mcMain.x + mcMain.width/2 - newBullet.width/2; 
     newBullet.y = mcMain.y; 
     //then we add the bullet to stage 
     bulletContainer.addChild(newBullet); 
    } 
} 
//this listener will listen for keys being released 
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeysUp); 
function checkKeysUp(event:KeyboardEvent):void{ 
    //making the booleans false based on the keycode 
    if(event.keyCode == 37 || event.keyCode == 65){ 
     leftDown = false; 
    } 
    if(event.keyCode == 38 || event.keyCode == 87){ 
     upDown = false; 
    } 
    if(event.keyCode == 39 || event.keyCode == 68){ 
     rightDown = false; 
    } 
    if(event.keyCode == 40 || event.keyCode == 83){ 
     downDown = false; 
    } 
} 

下面是從敵人的源代碼。

//This is the basic skeleton that all classes must have 
package{ 
    //we have to import certain display objects and events 
    import flash.display.MovieClip; 
    import flash.events.*; 
    //this just means that Enemy will act like a MovieClip 
    public class Enemy extends MovieClip{ 
     //VARIABLES 
     //this will act as the root of the document 
     //so we can easily reference it within the class 
     private var _root:Object; 
     //how quickly the enemy will move 
     private var speed:int = 5; 
     //this function will run every time the Bullet is added 
     //to the stage 
     public function Enemy(){ 
      //adding events to this class 
      //functions that will run only when the MC is added 
      addEventListener(Event.ADDED, beginClass); 
      //functions that will run on enter frame 
      addEventListener(Event.ENTER_FRAME, eFrame); 
     } 
     private function beginClass(event:Event):void{ 
      _root = MovieClip(root); 
     } 









     private function eFrame(event:Event):void{ 
      //moving the bullet up screen 
      y += speed; 
      //making the bullet be removed if it goes off stage 
      if(this.y > stage.stageHeight){ 
       removeEventListener(Event.ENTER_FRAME, eFrame); 
       _root.removeChild(this); 
      } 

      //checking if it is touching any bullets 
      //we will have to run a for loop because there will be multiple bullets 
      for(var i:int = 0;i<_root.bulletContainer.numChildren;i++){ 
       //numChildren is just the amount of movieclips within 
       //the bulletContainer. 

       //we define a variable that will be the bullet that we are currently 
       //hit testing. 
       var bulletTarget:MovieClip = _root.bulletContainer.getChildAt(i); 


       //now we hit test 
       if(hitTestObject(bulletTarget)){ 
        //remove this from the stage if it touches a bullet 
        removeEventListener(Event.ENTER_FRAME, eFrame); 
        _root.removeChild(this); 
        //also remove the bullet and its listeners 
        _root.bulletContainer.removeChild(bulletTarget); 
        bulletTarget.removeListeners(); 
        //up the score 
        _root.score += 5; 
       } 
      } 

      //hit testing with the user 
      if(hitTestObject(_root.mcMain)){ 
       //losing the game 
       _root.gameOver = true; 
       _root.gotoAndStop('lose'); 
      } 

      if(_root.gameOver){ 
       removeEventListener(Event.ENTER_FRAME, eFrame); 
       this.parent.removeChild(this); 
      } 
     } 
     public function removeListeners():void{ 
      this.removeEventListener(Event.ENTER_FRAME, eFrame); 
     } 
    } 
} 
+0

好建議強類型...但在REG導致實際錯誤:如果您使用調試Flash播放器,它會告訴您錯誤發生的行號。 –

回答

0

有幾種設計錯誤在你的腳本:

  • ,因爲它不僅是多餘的,而且會導致糟糕的設計沒有爲根域。另外,當剪輯被刪除時,你不會清理(這是刪除的東西)。
  • _root可以爲null,因爲如果我沒有弄錯,Event.ADDED也會在DisplayObject添加到DisplayObjectContainer時調度。
  • 每個敵人一個Event.ENTER_FRAME處理程序已註冊。這可能會導致性能問題和spagetti代碼 - 讓容器處理其子項(在特定的上下文中搜索遊戲循環)。

我建議實施安全的刪除方法,當一個孩子想要刪除自己。

function remove():void { 
    if (parent) parent.removeChild(this); // otherwise an run time error might be thrown 
} 

而關於在eFrame中拋出的錯誤。這實在是哈特說,什麼是空:

  • 階段:這是唯一Event.ADDED_TO_STAGE
  • _root.bulletContainer後可用:您剛剛鍵入_root到對象,沒有進一步的信息給
  • _root。 mcMain:您剛剛鍵入_root到對象,給出進一步的信息

我只能推薦一個更清潔的方式來編碼,其中將包括以下

相關問題