首页 > 解决方案 > 如何修复此代码中未捕获的类型错误?

问题描述

我不相信我可以在扩展数组的函数之前设置变量的类型,并且它正在该函数中设置。所以,我不确定为什么会出现类型错误。

因此,一旦首次初始化,带有问题 playercontrollerf 的变量就会在整个数组中设置为 false。

如果我没有正确发布或违反任何礼仪,我提前道歉,因为我一直处于堆栈溢出状态,而且我对 javascript 和堆栈溢出也相对较新。此外,要实际查看代码在做什么,您必须将其切换到全屏。

我在 Chrome 中遇到的错误是

Uncaught TypeError: Cannot read property '127' of undefined
at gameTurn (main.js:76)
at endTurn (main.js:120)
at reposition (main.js:206)
at HTMLDocument.<anonymous> (main.js:233)

这是我的游戏代码

/* Dunegon Valley by heromedel all rights reserved */
function gameloop() { // Entire Game contained withing function
  var mainArray = []; // most game data will be held withing the array
  var mapSizeX = 32; // sets the height of the rendered map and corresponding array coordinates
  var mapSizeY = 128; // sets the width
  var idPos = {
    x: 16,
    y: 64
  }; // currently used to set player location and check for collisions
  var rendFlr = 0; // sets which floor to render
  var curFlr = 0; // sets which floor is currently accepting input 
  var maxlayout = 10; // sets the number of floors to generate
  var curTurnX = 0;
  var curTurnY = 0;
  var gameState = 0;


  var tile = { // lists charcters used for rendered tiles and objects
    player: "☺",
    bunny: "b",
    rabbit: "r",
    empty: ".",
    wall: "#",
    oak: "♠",
    maple: "♣",
    grass: "‚",
    tallgrass: "„",
    water: "≈"

  };

  function getRndInteger(min, max) { // returns random number from min to max number appears to not function predictably if min and max are the same number
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  function nl() { // Creates a new line in the rendered text
    GameScreen.innerText += "\n";
  }

  function gameTurn(cx, cy) { // progresses through each tile checking if its player controlled or not using the while statement in end turn
    if (mainArray[cx][cy]['playercontrolledf' + curFlr] === "true") {
      render(rendFlr);
      mainArray[cx][cy]['entTurnf' + curFlr] = "true";
      gameState = 1;
    }

    if (mainArray[cx][cy]['playercontrolledf' + curFlr] != "true") { // call functions for non player controlled tiles
      //mainArray[cx][cy]['entTurnf' + curFlr] = "true";

      if (mainArray[cx][cy]['entityf' + curFlr] === "bunny") {

        //alert("Bunny Turn" );
        mainArray[cx][cy]['entityf' + curFlr] = "rabbit" // to show that each bunny is getting selected this line changes the bunnny into a rabbit


      }

    }

    // progress to next turn / tile
    if (curTurnX < mapSizeX) {
      curTurnX++;
    }

    if (curTurnX === mapSizeX) {
      if (curTurnY < mapSizeY) {
        curTurnX = 0;
        curTurnY++;
      }

      if (curTurnX === mapSizeX) {
        if (curTurnY === mapSizeY) {
          alert("worked"); // why does this never trigger
          curTurnX = 0;
          curTurnY = 0;
        }
      }


    }
  }

  function endTurn() {
    while (gameState === 0) {
      gameTurn(curTurnX, curTurnY);
      //alert("Turn "+ (curTurnX + curTurnY));
      //render(rendFlr);
    }
  }

  function initMap(mapSizeX, mapSizeY) { // expands and populates the array
    for (var i = 0; i < mapSizeX; i++) {
      mainArray.push([]) // I belive this is only expaning it 2 dimesionaly and matching the height

      for (var j = 0; j < mapSizeY; j++) {
        for (var k = 0; k < maxlayout; k++) {
          const obj = mainArray[i][j] || {}; // creates on object to alter and add back into the main array
          obj['tilef' + k] = tile.empty;
          obj['terrainf' + k] = "empty";
          obj['solidf' + k] = "false";
          obj['entityf' + k] = "none";
          obj['playercontrolledf' + k] = "false";
          obj['entTurnf' + k] = "false";
          obj['finished' + k] = "false";
          mainArray[i][j] = obj;

          if (k > 0) {
            if (j == 0 || // wraps the underground floor 1 in walls
              j == mapSizeY - 1 ||
              i == 0 ||
              i == mapSizeX - 1) {
              mainArray[i][j]['terrainf' + k] = "wall";
              mainArray[i][j]['solidf' + k] = "Wall";
            }
          }

        }

        //else{                                 // unneeded as the above for j is already creating empties
        //mainArray[i][j].terrain = "empty";
        //mainArray[i][j].solid = "false";
        //}
      }
    }
  }


  function randAdd(odds, feature, solid, flr, type) { // A chance to add named feature and solid type
    for (var i = 0; i < mapSizeX; i++) {
      for (var j = 0; j < mapSizeY; j++) {
        if (mainArray[i][j][type + 'f' + flr] === "empty" || mainArray[i][j][type + 'f' + flr] === "none") {
          roll = getRndInteger(1, odds);
          if (roll === odds) {
            mainArray[i][j][type + 'f' + flr] = feature;
            mainArray[i][j]['solidf' + flr] = solid;
          }
        }
      }
    }
  }


  function genMaps() { // Inside this function each line uses randAdd to randomly add a terrain type to a specified floor 
    randAdd(200, "wall", "solid rock", 0, 'terrain');
    randAdd(100, "oak", "a tree", 0, 'terrain'); //  (odds,terrain,solid,floor,type) 
    randAdd(100, "maple", "a tree", 0, 'terrain');
    randAdd(2, "grass", "False", 0, 'terrain');
    randAdd(2, "tallgrass", "False", 0, 'terrain');
    randAdd(200, "bunny", "false", 0, 'entity');
    randAdd(3, "wall", "solid rock", 1, 'terrain');
    randAdd(2, "wall", "solid rock", 2, 'terrain');
    randAdd(1, "wall", "solid rock", 3, 'terrain');
    randAdd(1, "wall", "solid rock", 4, 'terrain');
    randAdd(1, "wall", "solid rock", 5, 'terrain');
    randAdd(1, "water", "false", 8, 'terrain');
    randAdd(1, "water", "false", 9, 'terrain');
  }



  function tileSelect() {
    for (var i = 0; i < mapSizeX; i++) {
      for (var j = 0; j < mapSizeY; j++) {

        if (mainArray[i][j]['entityf' + rendFlr] === "none") {
          mainArray[i][j]['tilef' + rendFlr] = tile[mainArray[i][j]['terrainf' + rendFlr]];
        } else {
          mainArray[i][j]['tilef' + rendFlr] = tile[mainArray[i][j]['entityf' + rendFlr]]
        }

      }
    }
  }

  function render(flr) { // displays the array tiles to the browser
    GameScreen.innerText = mainArray.map(arr => arr.map(cell => cell['tilef' + flr]).join("")).join("\n");
    nl();
    nl();
  }


  function reposition(xChange, yChange, strA) { // checks if target position is not blocked and if not moves the player
    if (mainArray[idPos.x + xChange][idPos.y + yChange]['solidf' + curFlr] === "false" ||
      mainArray[idPos.x + xChange][idPos.y + yChange]['solidf' + curFlr] === "False" ||
      mainArray[idPos.x + xChange][idPos.y + yChange]['solidf' + curFlr] === "") {
      idPos.x = idPos.x + xChange;
      idPos.y = idPos.y + yChange;
      mainArray[idPos.x][idPos.y]['entityf' + curFlr] = "player";
      mainArray[idPos.x - xChange][idPos.y - yChange]['entityf' + curFlr] = "none";
      GameLog.innerText = "You take a step to the " + strA
    } else {
      GameLog.innerText = "You can not enter " + mainArray[idPos.x + xChange][idPos.y + yChange]['solidf' + curFlr];
    }
    mainArray[idPos.x][idPos.y]['terrainf' + curFlr] != "empty" ?
      GameLog.innerText += "\n There is " + mainArray[idPos.x][idPos.y]['terrainf' + curFlr] + " in this spot" :
      GameLog.innerText += "\n There is nothing in this spot";
    GameLog.innerText += "\n \n Elevation " + (curFlr * 50 * -1);

    tileSelect();
    render(rendFlr);
    gameState = 0;
    endTurn();
  }



  //Startup
  initMap(32, 128);
  genMaps();
  mainArray[idPos.x][idPos.y]['entityf' + curFlr] = "player";
  mainArray[idPos.x][idPos.y]['playercontrolledf' + curFlr] = "true";
  //First Render
  tileSelect();
  render(rendFlr);





  document.addEventListener('keydown', function(event) {
    if (event.keyCode === 38) { // up arrow
      reposition(-1, 0, "North");
      //alert(curTurnX);
    }
    if (event.keyCode === 40) { // down arrow
      reposition(1, 0, "South");
    }
    if (event.keyCode === 37) { // left arrow
      reposition(0, -1, "West");
    }
    if (event.keyCode === 39) { // right arrow
      reposition(0, 1, "East");
    }
    if (event.keyCode === 190) { // period
      if (rendFlr < maxlayout - 1) {
        mainArray[idPos.x][idPos.y]['entityf' + (curFlr + 1)] = "player";
        mainArray[idPos.x][idPos.y]['entityf' + (curFlr)] = "none";
        curFlr++;
        rendFlr++;
        GameLog.innerText = "You descened. \n \n Elevation " + (curFlr * 50 * -1);
      }
      tileSelect();
      render(rendFlr);
    }
    if (event.keyCode === 188) { // comma
      if (rendFlr > 0) {
        mainArray[idPos.x][idPos.y]['entityf' + (curFlr - 1)] = "player";
        mainArray[idPos.x][idPos.y]['entityf' + (curFlr)] = "none";
        curFlr--;
        rendFlr--;
        GameLog.innerText = "You ascened. \n \n Elevation " + (curFlr * 50 * -1);
      }
      tileSelect();
      render(rendFlr);
    }
    //alert(event.keyCode);
  });
}



gameloop();
/* Dunegon Valley by heromedel all rights reserved */

.info {
  color: #7d7d7d;
  font-family: Lucida Console;
}

.info span {
  color: #ABABAB;
  font-family: Lucida Console;
  font-size: 0.5em;
}

#GameScreen {
  color: #000000;
  font-family: Lucida Console;
  font-weight: italic;
  margin-left: auto;
  margin-right: auto;
}

#GameLog {
  color: #000000;
  font-family: Lucida Console;
}
<!DOCTYPE html>
<!-- Dunegon Valley by heromedel all rights reserved -->
<html>

<head>
  <link rel="stylesheet" href="styles.css">
  <meta charset="utf-8">
  <title>Dungeon Valley</title>
</head>

<body>
  <br>
  <p class="info">Dungeon Valley.<br>
    <span class="">
    Taming the Borderlands.<br> v0.011 By heromedel.
  </span>
  </p>
  <span id="GameScreen"></span>
  <section id="GameLog">Arrow Keys to move.<br></section>
  <script src="main.js"></script>
</body>

</html>

标签: javascripttypeerror

解决方案


问题是curTurnY太大了。这段代码:

      if (curTurnY < mapSizeY) {
        curTurnX = 0;
        curTurnY++;
      }

让它变得太高。的最大值curTurnY应该是127。但是当值已经是 时127,此代码会将其递增到128数组外部的 。将条件更改为:

      if (curTurnY < mapSizeY-1) {
        curTurnX = 0;
        curTurnY++;
      }

检查所有其他条件是否存在类似错误。


推荐阅读