AS3:为什么用 .graphics 创建的一行出现在两个不同的地方,当用 parent.visible = false 删除时,只有一个出现?

AS3: Why is a line created with .graphics appearing in two different places and when removed with parent.visible = false, only one goes?

似乎没有人有这个问题,所以我问了这个问题,因为我花了几个小时试图调试它,但找不到解决方案;

本质上,我有一个名为 draw 的函数,它在我的文档 class:

中声明
public function draw(Target: MovieClip,mX: int,mY: int,lX: int,lY: int):void {
    Target.graphics.clear();
    Target.graphics.lineStyle(1,0x000000,1);
    Target.graphics.moveTo(mX,mY);
    Target.graphics.lineTo(lX,lY);  
}

我稍后调用它在两个不同的 MovieClips 上画两条线:

draw(Line,Line.mX,Line.mY,Mirror.x + (Mirror.width / 2),Line.lY);
draw(nextLine,(Mirror.x + (Mirror.width / 2)),200,(Mirror.x + (Mirror.width / 2)),0);

其中

var Line: MovieClip = new MovieClip();
var Mirror: MovieClip = new mirror();

Mirror是可拖动的,所以Mirror.x只要被拖动就会改变。

Line是用.graphics做的一行,Line.mX等于上次修改的Line.graphics.moveToX值。 Line.mY 是一样的,不过是针对Y坐标。我通过这样做设置这些值:

Line.mX = 0;
Line.mY = 200;
Line.lX = 550; 
Line.lY = 200;

但是无论我想用什么值来画线,lXlY 等于 Line.graphics.lineTo 的 X 和 Y 坐标。然后我使用 draw 函数绘制 Line,如下所示:

draw(Line,Line.mX,Line.mY,Line.lX,Line.lY);

然后它变得更复杂,因为实际上,Line 只是一组行中的一行,创建如下:

public var lines = [line0,line1,line2,line3,line4,line5,line6,line7,line8];

每一行都是这样创建的(0 分别被行号替换):

public var line0: MovieClip = new MovieClip();

然后我给每行一个数字和一个名字,将它们添加到舞台上并像这样隐藏它们:

for each(var setupLine:MovieClip in lines) {
    setupLine.num = (lines.indexOf(setupLine));
    setupLine.name = ('line' + setupLine.num);

    addChild(setupLine);
    setupLine.visible = false;
}

然后,在使 line0 可见之后,因为我需要在开始时看到它,我在 ENTER_FRAME 上 运行s 的函数中遍历每一行,并设置每次我 运行 循环时 nextLine 的值都不同:

for each(var Line:MovieClip in lines) {
    nextLine = this['line' + (Line.num + 1)];
}

在那个循环中,我然后循环遍历其他几个数组,然后检查与选定的 Line 和另一个数组中的另一个选定的 MovieClip 的冲突,我不会讨论这个问题,否则这个问题会更长比 node.js.

的代码

所以基本上,如果存在与两个 MovieClip 的冲突,我会画出我在问题顶部提到的那条线。但出于某种原因,虽然 Line 绘制正确,nextLine 绘制正确,但它的副本在 0 处跨 Y 轴绘制,并在 Y 轴上的 nextLine 处停止( nextLine 是垂直的,所以它在开始和结束时具有相同的 Y 值。

更奇怪的是,当我尝试隐藏 nextLine 如果与两个 MovieClip 的碰撞不再存在,使用此代码:

nextLine.visible = false;

它只隐藏了舞台顶部 运行 的 nextLine 版本,我一开始根本没打算创建它。


编辑
here is a link to the current source code
Here is a link to the entire project files with the original source code
copy/paste 来自 pastebin 的新源代码 link 获取新版本


提前致谢,

-拉夫

我知道怎么做了,代码是

package {

    import flash.events.*;
    import flash.utils.*;
    import flash.display.*;

    [SWF(backgroundColor="0xbdc3c7")]
    public class LightStage extends MovieClip {

        //import classes
        public var globeClass:Globe = new Globe();
        public var mirrorClass:Mirror = new Mirror();
        public var lineClass:Line = new Line();

        //create all stage objects
        public var curLine:Line
        public var nextLine:Line;

        public var curMirror:Mirror;

        //create containers
        public var mirrors:Vector.<Mirror> = new Vector.<Mirror>(); //a vector is an array, but every member has to be (or subclass) the specified class
        public var globes:Vector.<Globe> = new Vector.<Globe>();
        public var lines:Vector.<Line> = new Vector.<Line>();

        trace('lightstage: working');
        //create level object
        public var curLevel:int = -1;

        //create dependent variables
        public var kill: Boolean = true;

        //init function
        public function LightStage() {
            //setup MovieClips

            var i:int = 0;

            for (i = 0; i < 4; i++) {
                mirrors.push(new Mirror());
            }

            for (i = 0; i < 4;i++ ) {
                globes.push(new Globe());
            }

            var tmpLine:Line;
            for (i = 0; i < 10; i++) {
                tmpLine = new Line();
                lines.push(tmpLine);

                addChild(tmpLine);
                tmpLine.visible = false;
            }

            //create ENTER_FRAME listener
            stage.addEventListener(Event.ENTER_FRAME,enterFrame);

            //start the game
            levelUp();
        }


        //levelUp function
        public function levelUp() {
            curLevel++;

            curLine = lines[curLevel]; //set line to the current level 

            curLine.curX = 0; 
            curLine.curY = 200;
            curLine.draw(550, 200);

            curLine.visible = true;

            //show and position mirrors and globes
            curMirror = mirrors[curLevel];
            addChild(curMirror);
            curMirror.x = 250;
            curMirror.y = 350;

            var curGlobe:Globe = globes[curLevel];
            addChild(curGlobe);
            curGlobe.x = 100;
            curGlobe.y = 50;

            //set mirror types
            curMirror.gotoAndStop(2);

            trace("you are now on level " + (curLevel + 1) + "!");

        }

        //ENTER_FRAME function
        public function enterFrame(event:Event) {
            //line1.visible = true;

            for (var i:int = 0; i < lines.length;i++){
                if (i < lines.length - 1) nextLine = lines[i + 1]; //check for out of bounds before assignment next line

                if (lines[i].visible == true) {
                    kill = true;
                    for each(var mirror:Mirror in mirrors) {
                        if (lines[i].visible && mirror.stage && mirror.hitTestObject(lines[i])) {  //for efficiency, do the hit test last in the if statement
                            for each(var globe:Globe in globes) {
                                //Looped through Mirrors and Lines and checked for collision - if collision is present, we loop through globes here

                                if (nextLine && nextLine.stage) {
                                    addChild(nextLine);
                                }

                                //check for active globes
                                if (lines[i].visible && lines[i].hitTestObject(globe)) {
                                    //check if the selected line touches the selected globe - if it does then we will start the timer for that globe
                                    if (!globe.running){
                                        globe.start();
                                        //trace('timing');
                                        kill = false;
                                    }
                                }
                                else {
                                    globe.reset();
                                }

                                switch(mirror.currentFrame) {
                                    case 1:
                                        break;

                                    case 2:
                                        //trace('live a life you will remember' + Math.random());
                                        if(nextLine) nextLine.visible = true;
                                        lines[i].draw(mirror.x + (mirror.width / 2),lines[i].curY);
                                        if (nextLine) {
                                            nextLine.curX = mirror.x + (mirror.width / 2);
                                            nextLine.curY = 200;
                                            nextLine.draw(mirror.x + (mirror.width / 2), 0);
                                        }
                                        kill = false;
                                        break;
                                    case 3:
                                    case 4:
                                    case 5:
                                    case 6:
                                    case 7:
                                    case 8:
                                    case 9:
                                    case 10:
                                    case 11:
                                    case 12:
                                        trace(mirror.currentFrame);
                                        kill = false;
                                        break;
                                }
                            }
                        }
                        else if (lines[i].visible && mirror.stage && lines[i].stage){
                            if (kill && nextLine){
                                nextLine.graphics.clear();
                                nextLine.visible = false;
                            }
                        }
                    }
                }
            }
        }
    }

}

//MIRROR CLASS DECLARATION
import flash.events.MouseEvent;
class Mirror extends MovieClip {
    trace('mirror: working');
    public function Mirror() {
        this.addEventListener(MouseEvent.MOUSE_DOWN,onDown,false,0,true);
    }

    private function onDown(e:MouseEvent):void {
        //add the mouse up listener on the stage, that way it's consistent even if the user drags so fast that the mouse leaves the bounds of the mirror
        stage.addEventListener(MouseEvent.MOUSE_UP, onUp, false, 0, true);
        this.startDrag();
    }

    private function onUp(e:MouseEvent):void {
        //we need to remove the listener from the stage now
        stage.removeEventListener(MouseEvent.MOUSE_UP, onUp, false);

        this.stopDrag();
    }
}

//LINE CLASS DECLARATION
import flash.display.Graphics;
class Line extends MovieClip {
    trace('line: working');
    public var curX:int;
    public var curY:int;

    public function Line():void {

    }

    public function draw(toX:int,toY:int):void {
        graphics.clear();
        graphics.lineStyle(1,0x000000,1);
        graphics.moveTo(curX,curY);
        graphics.lineTo(toX, toY);

        curX = toX;
        curY = toY;
    }
}

//GLOBE CLASS DECLARATION
import flash.display.MovieClip;
import flash.events.TimerEvent;
import flash.utils.Timer;
class Globe extends MovieClip {
    trace('globe: working');
    private var timer:Timer = new Timer(3 * 100, 5);

    public function Globe():void {
        timer = new Timer(300, 5);
        timer.addEventListener(TimerEvent.TIMER, repeatShine, false, 0, true);
    }

    public function reset():void {
        timer.reset();
    }

    public function start():void {
        timer.start();
    }

    public function get running():Boolean { return timer.running; };

    private function repeatShine(e:TimerEvent):void {

    }
}