2015-03-31 37 views
0

我是新來的(也是AS3相對較新的),請耐心等待。 我在2個星期前才發現OOP,在那之前,我只知道AS3最基本的知識。所以我確實做了很多改進,但有一件事讓我煩惱。如何從父類調用方法和屬性?

我永遠無法從父類中調用函數和方法。即使有setter和getters,子類也總是給我一個輸出錯誤。它看起來像這樣。

TypeError: Error #1009: Cannot access a property or method of a null object reference. 
at Axiom/clicked() 

這是我現在正在處理的AS3項目,它給了我這個問題。

這是項目的一些基本背景。

我有一個叫做Main的主類,還有一些其他的類叫做Axiom和Textbox。 Main將Axiom創建爲舞臺上已存在的動畫片段(背景)。 Axiom在點擊時創建文本框。 Axiom從Main調用一個名爲mouseClick的方法(播放聲音),Textbox從Axiom調用一些屬性(文本爲文本框)。

我試圖使用

MovieClip(this.parent).mouseClick(); 

,並在子類中聲明一個新的變量,像這樣。

private var main:Main; 
... 
main.mouseClick(); 

這引起了我的問題 - 我做錯了什麼,我該如何正確地做到這一點?

以下是供參考的類。而不是試圖調用父(很少是個好主意)的功能

Main.as

package { 
    import flash.ui.Keyboard; 
    import flash.events.Event; 
    import flash.events.EventDispatcher; 
    import flash.display.MovieClip; 
    import flash.events.KeyboardEvent; 
    import flash.ui.Mouse; 
    import flash.events.MouseEvent; 

    public class Main extends MovieClip { 
     // sound 
     private var music:Music = new Music(); 
     private var clickSound:Click = new Click(); 

     // instructions 
     private var instructions:Instructions = new Instructions(); 

     // mouse 
     private var cursor:Cursor = new Cursor(); 

     // player 
     private var player:Player = new Player(); 
     private var animationState:String = "standing"; 
     private var directionState:String = "right"; 

     // Axiom 
     private var axiom:Axiom = new Axiom(); 

     // movement 
     private var rightPressed:Boolean = false; 
     private var leftPressed:Boolean = false; 
     private var upPressed:Boolean = false; 
     private var downPressed:Boolean = false; 
     private var xMovement:Number = 0; 
     private var yMovement:Number = 0; 
     private var speed:Number = 22; 
     private var friction:Number = 0.9; 
     private var rDoubleTapCounter:int = 0; 
     private var lDoubleTapCounter:int = 0; 
     private var dDoubleTapCounter:int = 0; 
     private var uDoubleTapCounter:int = 0; 
     private var doubleTapCounterMax:int = 5; 
     private var running:Boolean = false; 

     public function Main() { 
      // constructor code 

      // mouse 
      stage.addChild(cursor); 
      cursor.mouseEnabled = false; 
      Mouse.hide(); 

      // instructions 
      instructions.x = 640; 
      instructions.y = 120; 
      stage.addChild(instructions); 

      // add player 
      player.x = 642; 
      player.y = 448.95; 
      player.gotoAndStop(directionState); 
      player.right.gotoAndStop(animationState); 
      addChild(player); 

      // add Axiom 
      axiom.x = 300; 
      axiom.y = -150; 
      back.addChild(axiom); 

      // keyboard events 
      stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); 
      stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased); 

      // music 
      music.play(0, int.MAX_VALUE); 

      // loop 
      stage.addEventListener(Event.ENTER_FRAME, loop); 
     } 

     private function loop(e:Event):void { 
      // set mouse 
      cursor.x = stage.mouseX; 
      cursor.y = stage.mouseY; 

      // set Movement to speed 
      if (rightPressed) { 
       if (upPressed) { 
        if (running || (rDoubleTapCounter <= doubleTapCounterMax && uDoubleTapCounter <= doubleTapCounterMax)) { 
         xMovement = speed * 2; 
         yMovement = speed * -2; 
        } else { 
         xMovement = speed; 
         yMovement = speed * -1; 
        } 
       } else if (downPressed) { 
        if (running || (rDoubleTapCounter <= doubleTapCounterMax && dDoubleTapCounter <= doubleTapCounterMax)) { 
         xMovement = speed * 2; 
         yMovement = speed * 2; 
        } else { 
         xMovement = speed; 
         yMovement = speed; 
        } 
       } else if (running || rDoubleTapCounter <= doubleTapCounterMax) { 
        xMovement = speed * 2; 
       } else { 
        xMovement = speed; 
       } 
      } else if (leftPressed) { 
       if (upPressed) { 
        if (running || (lDoubleTapCounter <= doubleTapCounterMax && uDoubleTapCounter <= doubleTapCounterMax)) { 
         xMovement = speed * -2; 
         yMovement = speed * -2; 
        } else { 
         xMovement = speed * -1; 
         yMovement = speed * -1; 
        } 
       } else if (downPressed) { 
        if (running || (lDoubleTapCounter <= doubleTapCounterMax && dDoubleTapCounter <= doubleTapCounterMax)) { 
         xMovement = speed * -2; 
         yMovement = speed * 2; 
        } else { 
         xMovement = speed * -1; 
         yMovement = speed; 
        } 
       } else if (running || lDoubleTapCounter <= doubleTapCounterMax) { 
        xMovement = speed * -2; 
       } else { 
        xMovement = speed * -1; 
       } 
      } else if (downPressed) { 
       if (dDoubleTapCounter <= doubleTapCounterMax || running) { 
        yMovement = speed * -2; 
       } else { 
        yMovement = speed * -1; 
       } 
      } else if (upPressed) { 
       if (uDoubleTapCounter <= doubleTapCounterMax || running) { 
        yMovement = speed * -2; 
       } else { 
        yMovement = speed * -1; 
       } 
      } 

      // double tap counter 
      if (rightPressed == false) { 
       rDoubleTapCounter++; 
      } 
      if (leftPressed == false) { 
       lDoubleTapCounter++; 
      } 
      if (downPressed == false) { 
       dDoubleTapCounter++; 
      } 
      if (upPressed == false) { 
       uDoubleTapCounter++; 
      } 

      // change labels 
      if (player.currentLabel != animationState) { 
       player.right.gotoAndStop(animationState); 
      } 

      // friction 
      xMovement *= friction; 
      yMovement *= friction; 

      // animationState and stop 
      if (Math.abs(xMovement) > 1) { 
       if (Math.abs(xMovement) > 22) { 
        animationState = "running"; 
        running = true; 
       } else { 
        animationState = "trotting"; 
        running = false; 
       } 
      } else { 
       animationState = "standing"; 
       xMovement = 0; 
      } 

      // right or left facing 
      if (xMovement > 0) { 
       player.scaleX = 1; 
      } else if (xMovement < 0) { 
       player.scaleX = -1; 
      } 


      //movement 
      if (back.x >= back.width/2 - 50) { 
       if (player.x >= 642 && xMovement > 0) { 
        player.x = 642; 
        back.x -= xMovement; 
       } else { 
        if (player.x <= player.width/2 && xMovement < 0) { 
         xMovement = 0; 
        } else { 
         player.x += xMovement; 
        } 
       } 
      } else if (back.x <= 1280 - back.width/2 + 50) { 
       if (player.x <= 642 - 30 && xMovement < 0) { 
        player.x = 642; 
        back.x -= xMovement; 
       } else { 
        if (player.x >= 1280 + 30 - player.width/2 && xMovement > 0) { 
         xMovement = 0; 
        } else { 
         player.x += xMovement; 
        } 
       } 
      } else { 
       back.x -= xMovement; 
      } 
     } 

     private function keyPressed(e:KeyboardEvent):void { 
      if (e.keyCode == Keyboard.RIGHT) { 
       rightPressed = true; 
      } else if (e.keyCode == Keyboard.LEFT) { 
       leftPressed = true; 
      } else if (e.keyCode == Keyboard.DOWN) { 
       downPressed = true; 
      } else if (e.keyCode == Keyboard.UP) { 
       upPressed = true; 
      } 
     } 

     private function keyReleased(e:KeyboardEvent):void { 
      if (e.keyCode == Keyboard.RIGHT) { 
       rightPressed = false; 
       rDoubleTapCounter = 0; 
      } else if (e.keyCode == Keyboard.LEFT) { 
       leftPressed = false; 
       lDoubleTapCounter = 0; 
      } else if (e.keyCode == Keyboard.DOWN) { 
       downPressed = false; 
       dDoubleTapCounter = 0; 
      } else if (e.keyCode == Keyboard.UP) { 
       upPressed = false; 
       uDoubleTapCounter = 0; 
      } 
     } 
     public function mouseClick():void { 
      clickSound.play(); 
     } 
    } 
} 

Axiom.as

package { 
    import flash.events.MouseEvent; 
    import flash.events.EventDispatcher; 
    import flash.display.MovieClip; 

    public class Axiom extends MovieClip { 
     private var speechBox:Textbox = new Textbox(); 
     private var speech:String = "Something came out of that pop."; 
     private var main:Main; 

     public function Axiom() { 
      // constructor code 
      this.addEventListener(MouseEvent.CLICK, onClickStage); 
      this.addEventListener(MouseEvent.CLICK, clicked); 
     } 
     private function onClickStage(e:MouseEvent):void { 
      trace(e.target,e.target.name); 
     } 

     private function clicked(e:MouseEvent):void { 
      main.mouseClick(); 
      stage.addChild(speechBox); 
      this.removeEventListener(MouseEvent.CLICK, clicked); 
     } 

     public function get words():String { 
      return speech; 
     } 

     public function removeThis():void { 
      this.addEventListener(MouseEvent.CLICK, clicked); 
      removeChild(speechBox); 
     } 
    } 
} 

Textbox.as

package { 
    import flash.events.MouseEvent; 
    import flash.display.MovieClip; 
    import com.greensock.TweenLite; 

    public class Textbox extends MovieClip{ 
     private var axiom:Axiom; 
     private var main:Main; 

     public function Textbox() { 
      // constructor code 
      this.x = 40; 
      this.y = 360; 
      this.textBox.text = axiom.words; 
      TweenLite.from(this, 0.3, {x: "10", alpha: 0}); 
      this.addEventListener(MouseEvent.CLICK, nextPage); 
     } 
     private function nextPage(e:MouseEvent):void{ 
      main.mouseClick(); 
      TweenLite.to(this, 0.3, {x: "-10", alpha: 0}); 
      MovieClip(this.parent).removeThis(); 
     } 
    } 
} 

回答

0

,改用事件。

在你的公理類:

package { 
...import statements 

public class Axiom extends MovieClip { 
    private var speechBox:Textbox = new Textbox(); 
    private var speech:String = "Something came out of that pop."; 
    private var main:Main; //this shouldn't be here, ideally, Axiom knows NOTHING about the main class. 

    public function Axiom() { 
     // constructor code 
     this.addEventListener(MouseEvent.CLICK, onClickStage); 
     this.addEventListener(MouseEvent.CLICK, clicked); 
    } 
    private function onClickStage(e:MouseEvent):void { 
     trace(e.target,e.target.name); 
    } 

    private function clicked(e:MouseEvent):void { 
     //main.mouseClick(); // unneccesary 
     dispatchEvent(e); //the event you caught by performing a click will be dispatched again, so that the parent can react to it 
     stage.addChild(speechBox); //Axiom might not have access to the stage, addChild would suffice 
     this.removeEventListener(MouseEvent.CLICK, clicked); 
    } 

    public function get words():String { 
     return speech; 
    } 

    public function removeThis():void { 
     this.addEventListener(MouseEvent.CLICK, clicked); 
     removeChild(speechBox); 
    } 
} 
} 

,並在您主類

axiom.addEventListener(MouseEvent.CLICK, onAximClicked); 

private function onAxiomClicked(e:MouseEvent):void{ 
    //now you can use the parents (in this case an Object of the Main class) functions 
    mouseClick(); 

} 
+0

謝謝你,這是非常有幫助! – ContraMuffin 2015-04-03 00:29:19

+0

哦,還有,我會怎樣從父類調用屬性? – ContraMuffin 2015-04-03 01:36:02

+0

您可以將父對象的引用傳遞給子類 – DodgerThud 2015-04-03 06:47:40