如何从父类调用方法和属性?

时间:2015-03-31 04:24:12

标签: actionscript-3 class oop

我是新来的(也是AS3的新手),所以请耐心等待。 我在2周前才发现OOP,在此之前,我只知道AS3最基本的知识。所以我确实做了很多改进,但有一件事一直困扰着我。

我似乎永远不会从父类调用函数和方法。即使使用setter和getter,子类总是会给出输出错误。它看起来像这样。

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();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

不要试图调用父级的函数(很少是个好主意),而是使用事件。

在你的Axiom课程中:

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();

}