2015-03-31 56 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