2015-06-21 50 views
0

這與我幾周前問的問題類似,但不同的代碼和以前的解決方案不起作用。AS3 - removeChild認爲它的工作原理,但沒有刪除任何東西(沒有錯誤)

簡而言之,我創建了一個tile數組,其大小可以通過下拉菜單進行選擇。我想要在選擇新尺寸時刪除先前的網格。正如你在代碼中看到的那樣,我已經放置了一些故障來確保孩子存在,並且有一個父母,並且它通過了這兩個測試,但是沒有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); 

     } 

回答

2

我想在選擇新的大小要刪除以前的網格。

確實如此。但稍後將其添加回顯示列表。見我添加到您的以下代碼的註釋:

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  
} 

如果去掉容器,你做到這一點:您刪除的容器。那個容器的孩子仍然是那個容器的孩子。當您再次添加容器時,將其與其之前的所有子項一起添加,這又使它們再次可見。

如果您稍後將其添加回來,那麼在刪除tiles時沒有意義。

而不是刪除tiles,你想刪除所有的孩子。 爲此,您可以使用允許您刪除所有子項的removeChildren()方法。 但是,您可以簡單地將tiles替換爲一個新的空容器。畢竟,如果你扔掉所有的孩子,重用單親容器的好處可以忽略不計。


failsafes到位,以確保兒童存在,並且有一個家長, 其實,你沒有。事實上,這個條件爲真:

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

並不能保證這條線:

removeChild(tiles); 

將執行沒有問題。我把它留給你閱讀有關contains()的文檔,看看爲什麼這不是故障安全。在你的情況下,它可能工作,但仍然,這不會一直工作。一般來說,這些「失敗者」通常用作「修補程序」,以修補某些意外的行爲。這種出乎意料的行爲總是由於缺乏對事件的理解以及對潛在問題的根源缺乏興趣而造成的。

你清楚地表明瞭對問題的興趣。我希望你們同意這種「失敗保險」並沒有挽救任何東西。不要將錯誤的代碼行包裝到故障安全中(可能不像您想象的那樣安全),請嘗試解決潛在問題,並瞭解造成問題的原因。

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

+0

謝謝你的詳細回覆!我絕對喜歡學習爲什麼,而不僅僅是如何。我閱讀了removeChildren(),它的工作原理非常完美,並且感謝你的解釋,我明白了爲什麼它之前沒有工作,以及爲什麼我的「失敗者」實際上沒有做我想做的事情(或者是,但沒有完成任何事情有用)。再次感謝你! – jdfinch3

相關問題