2013-04-24 3 views
0

메인 클래스가 마우스를 클릭/끌 때 '타일'무비 클립의 자식으로 Tile 클래스 인스턴스를 추가하는 타일 기반 레벨 편집기를 코딩하려고합니다. 컨테이너에 타일을 추가 할 수 있지만 스테이지에 표시되지만 지울 때 타일을 제거 할 수 없습니다. 그것은 나에게 다음과 같은 오류가 발생합니다오류 2025는 removeChild를 시도 할 때 추가 된 위치를 포함하지 않습니다.

Error #2025: The supplied DisplayObject must be a child of the caller. 
    at flash.display::DisplayObjectContainer/removeChild() 
     at Main/Draw() 
     at Main/::Go() 

또한 타일이 타일 컨테이너 안에 있는지를 확인하면 부모가 null이라는 것을 알려줍니다.

그래서 약간의 도움이 필요하십니까? 유사한 문제로 다른 질문을 시도했지만 아무도 내 문제와 가까워 보이지 않았습니다. 다음 코드는 문제를 일으키는

package { 
    import flash.display.MovieClip; 
    import flash.display.Sprite; 
    import flash.display.Stage; 
    import flash.display.StageScaleMode; 
    import flash.display.StageAlign; 
    import flash.events.Event; 
    import flash.events.MouseEvent; 
    import flash.events.KeyboardEvent; 
    //import flash.events.TimerEvent.updateAfterEvent; 

    public class Main extends MovieClip { 

     //containers 
     var lines:Sprite = new Sprite(); 
     var tiles:Sprite = new Sprite(); 

     // Grid data 
     var tileW:int = 20; 
     var tileH:int = 20; 
     var gridW:int = 20;//(inputWidth); 
     var gridH:int = 20;//(inputHeight); 
     var gridX:int = 50; 
     var grixY:int = 50; 
     var level:Array; 

     //Drawing variables 
     var go:Boolean = false; 
     var erase:Boolean = false; 

     var default_tile:int = 1; 
     var type:int; 

     var rect:Object = {x:100, y:50, width:(gridW * tileW)/100, height:(gridH * tileH)/100}; 

     //menus 
     var sizeMenu:SizeMenu = new SizeMenu(); 

     var current:Tile = new Tile(); 

     public function Main():void { 

      //Flash alignment and resizing 
      stage.scaleMode=StageScaleMode.NO_SCALE; 
      stage.align=StageAlign.TOP_LEFT; 

      stage.addChild(lines); 
      lines.x = rect.x; 
      lines.y = rect.y; 

      stage.addChild(tiles); 
      tiles.x = rect.x; 
      tiles.y = rect.y; 

      stage.addChild(sizeMenu); 

      stage.addChild(current); 
      current.x = 50; 
      current.gotoAndStop(default_tile); 
      stage.addEventListener(MouseEvent.MOUSE_DOWN, Go); 
      stage.addEventListener(MouseEvent.MOUSE_UP, Go); 
      stage.addEventListener(MouseEvent.MOUSE_MOVE, Go); 
      stage.addEventListener(KeyboardEvent.KEY_DOWN, ToggleErase); 
      stage.addEventListener(KeyboardEvent.KEY_UP, ToggleErase); 

      Setup(); 

     } 
     //Draws grid lines 
     private function Setup():void { 
      trace("Drawing Grid..."); 
      // create an empty array 
      level = new Array(gridH); 
      for (var i=0; i < gridW; i++) { 
       level[i] = new Array(gridW); 
      } 

      // attach lines to create a grid 
      for (var k=0; k <= gridH; k++) { 
       var line = new Line(); 
       line.name = "line"+k; 
       line.scaleX = rect.width; 
       line.y = tileH * k; 
       lines.addChild(line); 

       for (var j=0; j <= gridW; j++) { 
        line = new Line(); 
        line.name = "line"+j+"_"+k; 
        line.scaleX = rect.height; 
        line.x = tileW * j; 
        line.rotation = 90; 
        lines.addChild(line);     
       } 
      } 
      type = default_tile; 
      trace("Done drawing grid!"); 
     } 
     //Decided if drawing is possible 
     private function Go(e:MouseEvent):void { 
      if (e.type == "mouseDown") { 
       go = true; 
       Draw(e); 
      } 
      if (e.type == "mouseUp") { 
       go = false; 
      } 
      if (e.type == "mouseMove") { 
       if (go) { 
        Draw(e); 
       } 
       //e.updateAfterEvent(); 
      } 
     } 
     //Toggles erase 
     private function ToggleErase(e:KeyboardEvent):void{ 
      if (e.shiftKey){ 
       erase = true; 
      } 
      if (e.type == "keyUp"){ 
       erase = false; 
      } 
     } 


     // attaches the tiles when drawn on the grid 
     public function Draw(e:MouseEvent) { 
      var x = mouseX; 
      var y = mouseY; 
      var cx = Math.floor((x - rect.x)/tileW); 
      var cy = Math.floor((y - rect.y)/tileH); 



      if (cx >= 0 && cx < gridW && cy >= 0 && cy < gridH) { 
       var target = e.currentTarget; 
       if (!erase) { 
        if (tiles.contains(target)){ 
         trace("Contained!"); 
         tiles.removeChild(target); 
        } 

        var tile = new Tile(); 
        tiles.addChild(tile); 
        tile.name = ("t_" + cy + "_" + cx); 
        tile.x = (tileW * cx); 
        tile.y = (tileH * cy); 
        tile.gotoAndStop(type); 
        level[cy][cx] = type; 

       } else { 
        if (tiles.contains(target)){ 
         trace("Contained!"); 
         tiles.removeChild(target); 
        } 

        level[cy][cx] = default_tile - 1; 
       } 
      } 
     } 
     //Cleans the grid and redraws it 
     private function ResetGrid():void { 
      level = null; 

      //Delete tiles 
      while (tiles.numChildren) { 
       tiles.removeChildAt(0); 
      } 
      //Delete lines 
      while (lines.numChildren) { 
       lines.removeChildAt(0); 
      } 
      gridW=20; 
      gridH=20; 
      rect.width = (gridW * tileW)/100; 
      rect.height = (gridH * tileH)/100; 
     } 
     // updates the current-clip 
     private function update() { 
      current.gotoAndStop(type); 
     } 
    } 
} 

답변

0

내 문제를 해결 한! 모든 타일 인스턴스에는 추가 될 때 눈금의 위치에 따라 이름이 지정됩니다. 마우스가 가리키는 대상을 대상으로하는 대신 getChildByName(); 특정 이름의 객체가 이미 있는지 검색하고 삭제 된 경우 삭제합니다.

if (cx >= 0 && cx < gridW && cy >= 0 && cy < gridH) { 
    var target = tiles.getChildByName("t_" + cy + "_" + cx); 

    if (!erase) { 
     if (target){ 
      tiles.removeChild(target); 
     } 
     var tile = new Tile(); 
     tiles.addChild(tile); 
     tile.name = ("t_" + cy + "_" + cx); 
     tile.x = (tileW * cx); 
     tile.y = (tileH * cy); 
     tile.gotoAndStop(type); 
     level[cy][cx] = type; 
    } else { 
     if (target){ 
      tiles.removeChild(target); 
     } 
     level[cy][cx] = default_tile - 1; 
    } 
} 
2

, 기본적으로 동일한 개체를 두 번 removeChild을 요구하고있다. 코드에서

if (tiles.contains(target)){ 
    trace("Contained!"); 
    tiles.removeChild(target); 
} 
tiles.removeChild(target); 
+0

나는 그 라인을 알고있다. 그 줄을 제거하면 오류가 표시되는 것을 막을 수 있기 때문에 오류를 복제 할 때 거기에 그대로 둡니다. 그러나 타일을 전혀 제거하지는 않습니다. – Illogical

+0

if로 들어가서'Contained'를 추적합니다. 오류가 없다면 타일에서 제거하는 중임을 의미합니다. 디버깅을 시도하고 대상이 실제로 타일에서 제거되었는지 확인하십시오. –

+0

여러 번 디버깅을 시도했습니다. 그것은 추적하지도 않으며 아무것도 제거하지도 않습니다. 그것은 어떻게 든 플래시가 '타일'컨테이너 대신에 다른 것을 추가한다고 생각합니다. – Illogical

0

, 난 당신이 타일을 제거 할 수있는 능력을 가지고 있음을 발견하고이 블록의 끝에서 다시 제거하려고 :

 if (!erase) { 
      if (tiles.contains(target)){ 
       trace("Contained!"); 
       tiles.removeChild(target); 
      } 

      var tile = new Tile(); 
      tiles.addChild(tile); 
      tile.name = ("t_" + cy + "_" + cx); 
      tile.x = (tileW * cx); 
      tile.y = (tileH * cy); 
      tile.gotoAndStop(type); 
      level[cy][cx] = type; 

     } else { 
      if (tiles.contains(target)){ 
       trace("Contained!"); 
       tiles.removeChild(target); 
      } 
      // this is going to throw an error 
      tiles.removeChild(target); 
+0

그건 말이되지 않습니다. 자녀의 경우 테스트를 조건으로 둘 다 포장했습니다. 어떤 라인이 에러를 발생 시키는가? 나는 그 수표로 어떻게 오류를 얻을 수 있는지 보지 못한다. – prototypical

+0

더 나은 설명을 드리겠습니다 : 조건부 검사는 오류를 나타내지 않지만 대상 자식도 제거하지 않습니다. 플래시가 아무 것도하지 않은 것 같습니다. 분명히 아이가 추가 된 부모가 아니기 때문입니다. – Illogical

+1

아마도 정확한 정보와 명확하고 간결한 계정으로 게시물을 업데이트해야합니다. 먼저 ... 게시 설정으로 이동하여 "디버깅 허용"을 활성화하여 런타임 오류에 줄 번호를 부여하십시오. 또한 코드를 단계별로 실행할 때 변수 값을 확인할 수 있도록 디버거에 익숙해 져야하므로 사용자가 가정 한 값을 가지고 있는지 확인할 수 있습니다. – prototypical

0

쉬운에 그것을 확인 Tile에 대한 클래스를 만들고 remove 메서드를 사용하십시오. 이런 식으로 뭔가가 :

class Tile extends Sprite 
{ 
    public function remove():void 
    { 
     if(parent) parent.removeChild(this); 
    } 
} 

이렇게하면 간단하게 수행 할 수 있습니다

tile.remove();