AS3 - removeChild 认为它在工作,但没有删除任何东西(没有错误)

AS3 - removeChild thinks it's working, but isn't removing anything (no error)

这与我几周前提出的问题类似,但不同的代码和以前的解决方案不起作用。

简而言之,我正在创建一个图块数组,可以通过下拉菜单选择其大小。我希望在选择新尺寸时删除以前的网格。正如您在代码中看到的那样,我已经放置了故障保护以确保子项存在并有一个父项,并且它通过了这两个测试,但没有 removeChild。

public class gridtest extends MovieClip {
    public var gridSize:Number = 225;
    public var gridBreak:Number = 15;
    public var tilesArray = new Array();
    public var tiles:MovieClip = new MovieClip();
    public var MAX_ROWS:Number = 15;
    public var MAX_COLS:Number = 15;
    public var dropDwn:MovieClip;
    //info array for the dropdown menu
    public var dropDArray:Array = new Array({label:"Select Shop Size", data:0},{label:"Size 0 - 15x15", data:225},{label:"Size 1 - 18x15", data:270},{label:"Size 2 - 18x18", data:324},
                                            {label:"Size 3 - 21x18", data:378},{label:"Size 4 - 21x21", data:441},{label:"Size 5 - 24x21", data:504},
                                            {label:"Size 6 - 24x24", data:576},{label:"Size 7 - 27x24", data:648},{label:"Size 8 - 27x27", data:729},
                                            {label:"Size 9 - 30x27", data:810},{label:"Size 10 - 30x30", data:900},{label:"Size 11 - 33x30", data:990},
                                            {label:"Size 12 - 33x33", data:1089},{label:"Size 13 - 36x33", data:1188},{label:"Size 14 - 36x36", data:1296},
                                            {label:"Size 15 - 39x36", data:1404},{label:"Size 16 - 39x39", data:1521},{label:"Size 17 - 42x39", data:1638},
                                            {label:"Size 18 - 42x42", data:1764});

    public function gridtest():void {
        //create dropdown menu based off http://www.codingcolor.com/as3/as3-drop-down-menu/
        dropDwn = new DropDown();
        dropDwn.x = 50;
        dropDwn.y = 770;
        dropDwn.init(dropDArray,150, 20,"up");
        addChild(dropDwn);
        dropDwn.addEventListener(Event.CHANGE,onDropDown);  
        }

        public function onDropDown(event:Event){
        gridSize = event.target.selectedObject.data;
        switch (gridSize){

    case 225:
    MAX_ROWS = 14;
    MAX_COLS = 14;
    break;

    case 270:
    MAX_ROWS = 17;
    MAX_COLS = 14;
    break;

    case 324:
    MAX_ROWS = 17;
    MAX_COLS = 17;
    break;

    case 378:
    MAX_ROWS = 20;
    MAX_COLS = 17;
    break;

    case 441:
    MAX_ROWS = 20;
    MAX_COLS = 20;
    break;

    case 504:
    MAX_ROWS = 23;
    MAX_COLS = 20;
    break;

    case 576:
    MAX_ROWS = 23;
    MAX_COLS = 23;
    break;

    case 648:
    MAX_ROWS = 26;
    MAX_COLS = 23;
    break;

    case 729:
    MAX_ROWS = 26;
    MAX_COLS = 26;
    break;

    case 810:
    MAX_ROWS = 29;
    MAX_COLS = 26;
    break;

    case 900:
    MAX_ROWS = 29;
    MAX_COLS = 29;
    break;

    case 990:
    MAX_ROWS = 32;
    MAX_COLS = 29;
    break;

    case 1089:
    MAX_ROWS = 32;
    MAX_COLS = 32;
    break;

    case 1188:
    MAX_ROWS = 35;
    MAX_COLS = 32;
    break;

    case 1296:
    MAX_ROWS = 35;
    MAX_COLS = 35;
    break;

    case 1404:
    MAX_ROWS = 38;
    MAX_COLS = 35;
    break;

    case 1521:
    MAX_ROWS = 38;
    MAX_COLS = 38;
    break;

    case 1638:
    MAX_ROWS = 41;
    MAX_COLS = 38;
    break;

    case 1764:
    MAX_ROWS = 41;
    MAX_COLS = 41;
    break;
    }

    var tilesArray:Array = new Array();


        //initalize the arrays
        for (var row = 0; row <= MAX_ROWS; row++)
        {
            var boolArray:Array = new Array();

            for (var col = 0; col <= MAX_COLS; col++){
                boolArray.push(false);
            }

            tilesArray.push(boolArray);
        }

        for (var row = 0; row <= MAX_ROWS; row++)
        {
            for (var col = 0; col <= MAX_COLS; col++){

                tilesArray.push(1); ;
            }
        }

        buildLevel(tilesArray);

    }

        public function buildLevel(s:Array){

            //This reports back "tiles removed", but the tiles are still on the screen...

            if(tiles != null && this.contains(tiles)){ 
                removeChild(tiles);
                trace("tiles removed");
            }

            for(var i=0; i  < MAX_ROWS + 1; i++){
                for(var o=0; o < MAX_COLS + 1; o++){
                    var currentTile:Tiles = new Tiles();
                    currentTile.x = i*15;
                    currentTile.y = o*15;
                    currentTile.name = "t"+i+"by"+o;
                    tiles.addChild(currentTile);
                    currentTile.gotoAndStop(int(s[o][i]));

                }
            }

                tiles.x = 400 - tiles.width/2;
                tiles.y = 360 - tiles.height/2;
                addChild(tiles);

        }

I want the previous grid to be removed when a new size is selected.

你确实这样做了。但是您稍后将其添加回显示列表。请参阅我在下面添加到您的代码中的评论:

public function buildLevel(s:Array){
    //This reports back "tiles removed", but the tiles are still on the screen...

    if(tiles != null && this.contains(tiles)){ 
        removeChild(tiles);     // <--------------------you remove tiles here                   
        trace("tiles removed");
    }

    for(var i=0; i  < MAX_ROWS + 1; i++){
        for(var o=0; o < MAX_COLS + 1; o++){
            var currentTile:Tiles = new Tiles();
            currentTile.x = i*15;
            currentTile.y = o*15;
            currentTile.name = "t"+i+"by"+o;
            tiles.addChild(currentTile);
            currentTile.gotoAndStop(int(s[o][i]));
        }
    }

    tiles.x = 400 - tiles.width/2;
    tiles.y = 360 - tiles.height/2;
    addChild(tiles);        // <--------------------but you add it again here       
}

如果您移除容器,您就是这样做的:移除容器。该容器的 children 仍然是该容器的 children。当您再次添加容器时,您将添加它及其之前的所有 children,这也使它们再次可见。

添加 children 的同时删除 tiles 是没有意义的,如果以后再添加回来的话。

您不想删除 tiles,而是要删除所有 children。 为此,您可以使用允许您删除所有 children 的 removeChildren() 方法。 但是,您可以简单地将 tiles 替换为一个新的空容器。毕竟,如果你扔掉所有 children,重用单个 parent 容器的好处可以忽略不计。


failsafes in place to ensure that the child exists and has a parent, Actually, you didn't. The fact that this condition is true:

tiles != null && this.contains(tiles)

不保证这一行:

removeChild(tiles); 

将毫无问题地执行。我让您阅读有关 contains() 的文档以了解为什么这不是故障保护。在您的情况下,它可能有效,但仍然不会一直有效。一般来说,那些 "failsafes" 通常用作 "hotfixes",以修补一些意外行为。这种意外行为几乎总是由于不了解正在发生的事情以及对潜在问题的根源缺乏兴趣造成的。

您通过询问清楚地表明了兴趣。我希望你同意这个 "failsafe" 没有保存任何东西。不要将错误的代码行包装到故障保护中(这可能不像您认为的那样安全),而是尝试解决潜在的问题并深入了解导致问题的原因。

我希望我能提供一些见解。