2011-11-08 10 views
-1

次のコードに問題があります。 迷路関数NewMazeに再帰中に破損しているようです。私は放火犯を通してそれを実行し、私は次のエラーを取得:Javascriptの再帰が予期せず中断 - 警告の長いコード

parent is undefined: line 97 newmaze_generator.js 
    [Break On This Error] self.visited = function() {return parent.visited();}; 

をそして私はそれも本当の問題であれば、それは、不定になる理由はわかりません。

私はこれがたくさん求めていることを知っていますので、初心者のjavascriptプログラマーを助けるような気がしなければ、時間を無駄にしないでください。物事を簡単にするために、私は自分のウェブサイト上にコード全体を持っていますので、実際には何もしません。サイドノートでは

http://level2games.com/games/dungeons/dungeons.html

これはだけなので、私は簡単にダムミスを犯している可能性がjavascriptのプログラミングに私の第二の進出です。私は考え出し

マイMazeGenerator

function NewMaze(_grid) { 
    var self = this; 
    var stack = new Array(); 
    var grid = _grid; 

    /** 
    * A recursive depth-first-search style maze generator 
    */ 
    self.maze = function() { 
     var randx = Math.floor(Math.random()*(grid.getWidth())); 
     var randy = Math.floor(Math.random()*(grid.getHeight())); 
     var startOfMaze = new MyCell(grid.getCell(randx, randy)); 
     stack.push(startOfMaze); 
     mazeHelper(startOfMaze); 
    }; 

    /** 
    * Internal recursive method used by maze. 
    * A depth-first-search style algorithm. 
    * @param mycell current cell 
    * @returns {Boolean} true once finished 
    */ 
    function mazeHelper(myCell) { 
     var neighbors = myCell.getOpenNeighbors(); 
     myCell.markVisited(); 
     if (neighbors.length > 0) { 
      var next = Math.floor(Math.random()*(neighbors.length)); 
      var nextCell = neighbors[next]; 
      stack.push(nextCell); 
      removeWall(myCell, nextCell); 
//   alert(myCell.getParent().getArrayLocation().getX()+" , "+myCell.getParent().getArrayLocation().getY()); 
      mazeHelper(nextCell); 
     } else { 
      alert("else"); 
      if (stack.length == 0) return true; 
      else mazeHelper(stack.pop()); 
     }; 
    }; 

    /** 
    * Removes the wall between the given cells 
    * @param fromCell 
    * @param toCell 
    */ 
    function removeWall(fromCell, toCell) { 
     var xDif = toCell.getParent().getArrayLocation().getX() - fromCell.getParent().getArrayLocation().getX(); 
     var yDif = toCell.getParent().getArrayLocation().getY() - fromCell.getParent().getArrayLocation().getY(); 

     if (xDif == -1) toCell.seWall = false; // if moving up x axis 
     if (xDif == 1) fromCell.seWall = false; // if moving down x axis 
     if (yDif == -1) toCell.swWall = false; // if moving up y axis 
     if (yDif == 1) fromCell.swWall = false; // if moving down y axis 

    }; 

    /** 
    * @returns an instance of 'this' named self. 
    */ 
    self.getSelf = function() {return self;}; 

    /** 
    * Inner class that is an extension of Cell class 
    * @param cell the parent cell 
    * @returns {MyCell} instance of 'this' child 
    */ 
    function MyCell(cell) { 
     var self = this; 
     var parent = cell; 

     /** 
     * Marks the referenced cell as visited using the super class's visited method. 
     */ 
     self.markVisited = function() {parent.markVisited();}; 

     self.visited = function() {return parent.visited();}; 

     /** 
     * Creates and returns an array of neighbors that have not been visited. 
     * @returns {<MyCell>Array} an array of adjacent cells that have not been visited. 
     */ 
     self.getOpenNeighbors = function() { 
      var neighbors = new Array(); 

      var tc0, tc1, tc3, tc4; 
      var parentX = parent.getArrayLocation().getX(); 
      var parentY = parent.getArrayLocation().getY(); 

      tc0 = new MyCell(grid.getCell(parentX-1, parentY)); 
      tc1 = new MyCell(grid.getCell(parentX+1, parentY)); 
      tc2 = new MyCell(grid.getCell(parentX, parentY-1)); 
      tc3 = new MyCell(grid.getCell(parentX, parentY+1)); 

      if (tc0 != undefined && !tc0.visited()) neighbors.push(tc0); 
      if (tc1 != undefined && !tc1.visited()) neighbors.push(tc1); 
      if (tc2 != undefined && !tc2.visited()) neighbors.push(tc2); 
      if (tc3 != undefined && !tc3.visited()) neighbors.push(tc3); 

      return neighbors; 
     }; 

     /** 
     * @returns an instance of 'this' named self. 
     */ 
     self.getSelf = function() {return self;}; 

     /** 
     * @returns an instance of the 'super' class named parent. 
     */ 
     self.getParent = function() {return parent;}; 
    }; 
}; 

マイ迷路クラス

function NewGrid(context, gwidth, gheight) { 
    var self = this; // stores and instance of 'this' 
    var ctx = context; // local pointer to the context; 
    var width = 12;  // 12 is the default number of cells wide 
    var height = 12; // 12 is the default number of cells high 

    // Public Variables - needed by NewCell class, umm... please don't overwrite 
    NewGrid.FLOOR_COLOR = "#CABCAF"; // default base color - brown 
    NewGrid.WALL_COLOR = "#333333"; // default wall color - dark grey 
    NewGrid.CELL_WIDTH = FINAL_CELL_WIDTH;  // 200px is the default width 
    NewGrid.CELL_HEIGHT = FINAL_CELL_HEIGHT; // 100px is the default height 

    var cells = new Array(); // 2d array of cells, fully instantiated in constructHelper 
    contructHelper(gwidth, gheight); 

    /** 
    * Internal helper method (pseudo-constructor) 
    */ 
    function contructHelper(gwidth, gheight) { 
     if (gwidth != undefined && gheight != undefined) { 
      width = gwidth; 
      height = gheight; 
     }; 

     // Constructs the 2d array of cells i.e. cells[y] = x[] 
     cells = new Array(height); 
     for (var i = 0; i < cells.length; i++) { 
      cells[i] = new Array(height); 
     }; 

     gridBuilder(); 
    }; 

    function gridBuilder() { 
     var offSet = width * NewGrid.CELL_WIDTH/2; 
     for (var i = 0; i < cells.length; i++) { 
      for (var j = cells[i].length - 1; j >= 0; j--) { 
       var x = (j * NewGrid.CELL_WIDTH/2) - (i * NewGrid.CELL_WIDTH/2) + offSet; 
       var y = (i * NewGrid.CELL_HEIGHT/2) + (j * NewGrid.CELL_HEIGHT/2); 
       cells[i][j] = new NewCell(ctx, new Point(x,y), new Point(i,j)); 
      }; 
     }; 
    }; 

    /** 
    * @returns the width of the grid 
    */ 
    self.getWidth = function() {return width;}; 

    /** 
    * @returns the height of the grid 
    */ 
    self.getHeight = function() {return height;}; 

    /** 
    * draws the grid to the screen 
    * @param useViewport true if drawing only a portion 
    */ 
    self.drawMe = function(useViewport) { 
     if (!useViewport) { 
      // draws the full grid to the canvas 
      for (var i = 0; i < cells.length; i++) { 
       for (var j = cells[i].length - 1; j >= 0; j--) { 
        cells[i][j].drawMe(); 
       }; 
      }; 
      for (var i = 0; i < cells.length; i++) { 
       for (var j = cells[i].length - 1; j >= 0; j--) { 
        cells[i][j].drawWalls(); 
       }; 
      }; 
     } else { 
      // draws only the viewable portion of the grid to the canvas. 
      // not implemented yet 
     } 
    }; 

    self.getCell = function(x,y) { 
     if (x >= 0 && x < width) { 
      if (y >= 0 && y < height) { 
       return cells[x][y].getSelf(); 
      }; 
     }; 
     return undefined; 
    }; 

    /** 
    * @returns an instance of 'this' named self. 
    */ 
    self.getSelf = function() {return self;}; 

    /** 
    * Internal class for the viewable portion of the grid 
    * @param vpwidth (optional) number of cells to be displayed horizontally 
    * @param vpheight (optional) number of cells to be displayed vertically 
    */ 
    function ViewPort(vpwidth, vpheight) { 
     var self = this; 
     var width = 4; // 4 is the default number of cells wide 
     var height = 3; // 3 is the default number of cells high 
     constructHelper(vpwidth, vpheight); 

     /** 
     * Internal helper method (pseudo-constructor) 
     */ 
     function contructHelper(vpwidth, vpheight) { 
      if (vpwidth != undefined && vpheight != undefined) { 
       width = vpwidth; 
       height = vpheight; 
      }; 
     }; 

     /** 
     * @returns the width of the view port 
     */ 
     self.getWidth = function() {return width;}; 
     /** 
     * @returns the height of the view port 
     */ 
     self.getHeight = function() {return height;}; 

     /** 
     * @returns an instance of 'this' named self. 
     */ 
     self.getSelf = function() {return self;}; 
    }; 
}; 

マイセルクラス

/** 
* @param context the context on which to be drawn. 
* @param ccorners an array of points representing the 4 corners 
* @param cwidth (optional) the number of pixels wide the cell is. 
* @param cheight (optional) the number of pixels high the cell is. 
*/ 
function NewCell(context, origin, arrLoc) { 
    var self = this;   // stores and instance of 'this' 
    var ctx = context;   // local pointer to the context; 
    var corners = new Array(); // an array of points representing the corners in n-e-s-w order 
    var arrayLoc = arrLoc; // position in the cells array 
    var wallHeight = 5; // pixels used to draw the wall 

    self.swWall = true; //determines is a wall is present to the south-west 
    self.seWall = true; //determines is a wall is present to the south-east 

    var visited = false; // used by maze generator 

    contructHelper(origin); 

    /** 
    * Internal helper method (pseudo-constructor) 
    * @param origin is a Point representing the x,y value of the top corner 
    */ 
    function contructHelper(origin) { 
     corners[0] = new Point(origin.getX(), origin.getY());              // 0,0 
     corners[1] = new Point(origin.getX() + NewGrid.CELL_WIDTH/2, origin.getY() + NewGrid.CELL_HEIGHT/2); // 0+100,0+50 
     corners[2] = new Point(origin.getX(), origin.getY() + NewGrid.CELL_HEIGHT);         // 0, 0+100 
     corners[3] = new Point(origin.getX() - NewGrid.CELL_WIDTH/2, origin.getY() + NewGrid.CELL_HEIGHT/2); // 0-100, 0+50 
    }; 

    /** 
    * @returns the x,y value of the top corner as a Point 
    */ 
    self.getOrigin = function() {return corners[0];}; 

    self.getArrayLocation = function() {return arrayLoc;}; 

    /** 
    * @returns the x,y value of the center of the cell as a Point 
    */ 
    self.getCenter = function() {return new Point(corners[0].getX(), corners[0].getY() + NewGrid.CELL_HEIGHT/2);}; 

    /** 
    * draws the cell to the canvas using an array of points 
    * to from the corners and using (for temporary purposes) 
    * a floor color and wall color and wall height. 
    */ 
    self.drawMe = function() { 
     ctx.lineWidth = wallHeight; 
     ctx.fillStyle = NewGrid.FLOOR_COLOR; 
     ctx.beginPath(); 
     ctx.moveTo(corners[0].getX(),corners[0].getY()); 
     ctx.lineTo(corners[1].getX(),corners[1].getY()); 
     ctx.lineTo(corners[2].getX(),corners[2].getY()); 
     ctx.lineTo(corners[3].getX(),corners[3].getY()); 
     ctx.closePath(); 
     ctx.fill(); 
    }; 

    self.drawWalls = function() { 
     ctx.strokeStyle = NewGrid.WALL_COLOR; 
     if (seWall) { 
      ctx.beginPath(); 
      ctx.moveTo(corners[2].getX(),corners[2].getY()); 
      ctx.lineTo(corners[3].getX(),corners[3].getY()); 
      ctx.closePath(); 
      ctx.stroke(); 
     }; 

     if (swWall) { 
      ctx.beginPath(); 
      ctx.moveTo(corners[3].getX(),corners[3].getY()); 
      ctx.lineTo(corners[0].getX(),corners[0].getY()); 
      ctx.closePath(); 
      ctx.stroke(); 
     }; 
    }; 

    self.visited = function() {return visited;}; 

    self.markVisited = function() {visited = true;}; 

    /** 
    * @returns gets the array of the 4 neighboring cells 
    */ 
    self.getNeighbors = function() { 
     return neighbors; 
    }; 

    /** 
    * @returns an instance of 'this' named self. 
    */ 
    self.getSelf = function() {return self;}; 
}; 
+0

私の知る限り、あなたの '細胞'には、それらに関連する訪問されたメソッドがありません。それらはmyCellオブジェクトの親であるため、parent.visited()は未定義です。 –

+0

セルクラスには次のメソッドがあります:self.visited = function(){return visited;}; – Austin

+0

私はそれ以来、迷路ジェネレータの内部クラスMyCellの訪問された関数の中にtry-catchを追加しました。私は親がいないオブジェクトを捕まえています。なぜそれが起こるのか分かりません。 – Austin

答えて

0

さて、それ!私は愚かな間違いだった、それが良いことであろうとなかろうと、私は確信が持てません。機能が、私はそうに移行する可能隣人の配列に追加していない場合は、セルが未定義だったかどうかを確認するためにチェックをしていたgetOpenNeighborsで

は、ここで問題でした。まあ、未定義のチェックは間違って書かれました。私は、次のようなセルを定義していた:

tc0 = new MyCell(grid.getCell(parentX-1, parentY)); 

何のセルが、私はそれをやってみたかった、まさにある特定の場所に存在しない場合grid.getCell(x、y)のメソッドはundefinedを返すでしょう。私はそれは私のような書いた配列に追加されなかったことを確認するために行った検査でしかし

if (tc0 != undefined && !tc0.visited()) neighbors.push(tc0); 

まあ、明らかTC0または私は方法で作成したTC0-Xのオブジェクトのいずれか未定義ではない。私が必要としたのは、私がパラメタとして渡したオブジェクトが定義されていないかどうかをチェックすることでした。私はこのオブジェクトを親クラスまたはスーパークラスとして扱っていましたので、私のメソッドを使用することでした。getParent()そしてすべてがhunky-dooryになります。

if (tc0.getParent() != undefined && !tc0.visited()) neighbors.push(tc0); 

すべてが機能します。残念ながら、迷路は、私がそこで行ういくつかの問題を抱えているので、私は前進することができますように、見ていないように見えません。

関連する問題