javascript 如何在循环内向数组的坐标添加其他属性,而不删除数组的现有属性

标签 javascript arrays properties

我已将程序中的错误范围缩小到以下内容。

只要 maxlayout 等于 1,以下循环就可以工作,但如果它等于 2,则循环运行两次,然后原始值会被删除。

因此,如果循环运行一次,则 mainArray.tilef0 将等于tile.empty 但如果 tan 两次,那么 mainArray.tilef0 将是未定义的,并且 mainArray.tilef1 将等于tile.empty

对于地形和实体等其余属性也是如此。

for (var k = 0; k < maxlayout; k++){
       mainArray[i][j] = {
          ['tilef' + k]: tile.empty,
          ['terrainf' + k]: "empty",
          ['solidf' + k]: "false",
        };

Barmar 和 Henery 回答了我的问题,但我想我应该添加下面的整个代码。这样他们或其他人就可以看到它如何帮助我或其他人看看是否有更好的方法,例如在我需要帮助之前初始化数组。

下面是他们帮助我完成的功能版本和代码。

如果它很困惑,我深表歉意,我努力保持代码整洁,并且不知道所有标准的做事方式。但我添加了很多评论。

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 maxlayout = 3;
  
  
  var tile = {                                  // lists charcters used for rendered tiles and objects
    player: "☺",
    empty: ".",
    wall: "#",
    oak: "♠",
    maple: "♣",
    grass: "‚",
    tallgrass: "„"
    
  };

  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";
                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]['tilef' + k] = tile.wall;
                        mainArray[i][j]['terrainf' + k] = "wall";
                        mainArray[i][j]['solidf' + k] = "Wall";
                        }
                }
                
            }
        
        //else{                                 // un need as the above for j is already creating empties
            //mainArray[i][j].terrain = "empty";
            //mainArray[i][j].solid = "false";
        //}
      }
    }
  }
  
  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 randAdd(odds,feature,solid) {                        // A chance to add named feature and solid type or message if the "odds" or max number provided is rolled.
    for (var i = 0; i < mapSizeX; i++) {
        for (var j = 0; j < mapSizeY; j++) {
            if (mainArray[i][j].terrainf0 === "empty") {
             roll = getRndInteger(1,odds);
                if(roll === odds){
                    mainArray[i][j].terrainf0 = feature;
                    mainArray[i][j].tilef0 = tile[feature];
                    mainArray[i][j].solidf0 = solid;   
                }     
            }
        }
    }
  }
  
  function randAdd1(odds,feature,solid) {                      // Same as above function but for floor 1 and should eventually be merged into a single function
    for (var i = 0; i < mapSizeX; i++) {
        for (var j = 0; j < mapSizeY; j++) {
            if (mainArray[i][j].terrainf0 === "empty") {
             roll = getRndInteger(1,odds);
                if(roll === odds){
                    mainArray[i][j].terrainf1 = feature;
                    mainArray[i][j].tilef1 = tile[feature];
                    mainArray[i][j].solidf1 = solid;   
                }     
            }
        }
    }
  }

  function genMaps(){
    randAdd(200,"wall","solid rock");
    randAdd(100,"oak","a tree");
    randAdd(100,"maple","a tree");
    randAdd(2,"grass","False");
    randAdd(2,"tallgrass","False");
    randAdd1(1,"wall","solid rock");
  }

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

  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].solidf0 === "false" || 
        mainArray[idPos.x + xChange][idPos.y + yChange].solidf0 === "False" ||
        mainArray[idPos.x + xChange][idPos.y + yChange].solidf0 === "") {
      mainArray[idPos.x][idPos.y].tilef0 = tile[mainArray[idPos.x][idPos.y].terrainf0];
      idPos.x = idPos.x + xChange;
      idPos.y = idPos.y + yChange;
      mainArray[idPos.x][idPos.y].tilef0 = tile.player;
      GameLog.innerText = "You take a step to the " + strA 
    } 
    else {
      GameLog.innerText = "You can not enter " + mainArray[idPos.x + xChange][idPos.y + yChange].solidf0;
    }
    mainArray[idPos.x][idPos.y].terrainf0 != "empty" ?
        GameLog.innerText += "\n There is " + mainArray[idPos.x][idPos.y].terrainf0 + " in this spot" : 
        GameLog.innerText += "\n There is nothing in this spot";
    
    render(rendFlr);
  }

  //Startup
  initMap(32, 128);
  genMaps();
  mainArray[idPos.x][idPos.y].tilef0 = tile.player;
  //First Render
  render(rendFlr);

  document.addEventListener('keydown', function(event) {
    if (event.keyCode === 38) {
      reposition(-1, 0, "North");
    }
    if (event.keyCode === 40) {
      reposition(1, 0, "South");
    }
    if (event.keyCode === 37) {
      reposition(0, -1, "West");
    }
    if (event.keyCode === 39) {
      reposition(0, 1, "East");
    }
    if (event.keyCode === 190) {
        if(rendFlr < maxlayout) {rendFlr++}
      render(rendFlr);
    } if (event.keyCode === 188) {
        if(rendFlr > 0) {rendFlr--}
      render(rendFlr);
    }
    //alert(event.keyCode);
  });
}



gameloop();
.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>
<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.008 By heromedel.
  </span>
</p>
<section id="GameScreen"></section>
<section id="GameLog">Arrow Keys to move.<br></section>
    <script src="main.js"></script>
</body>
</html>

如果您想测试它,我建议运行该代码片段,然后单击全屏 方向键移动, 和 。将更改正在渲染的楼层。

最佳答案

Barmar 的答案指出了问题,但如果 mainArray[i][j] 未初始化,很可能会遇到 undefined 错误。所以像这样:

for (var k = 0; k < maxlayout; k++){
       const obj = mainArray[i][j] || {};       
       obj['tilef' + k] = tile.empty;
       obj['terrainf' + k] = "empty";
       obj['solidf' + k] = "false";
       mainArray[i][j] = obj;
}

关于javascript 如何在循环内向数组的坐标添加其他属性,而不删除数组的现有属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60536869/

相关文章:

javascript - HTML 不显示 Angularjs 的变量值

c# - 在 PropertyGrid C# 中显示 DebuggerDisplay

php - 查找多维数组中的重复值

javascript - TypeError : t. map 不是函数

javascript - ajax post后用服务器的值更新原始对象

javascript - 方法是javascript中属性的子集吗?

arrays - 如何避免 Matlab 在创建句柄对象数组作为对象属性时占用指数时间

javascript - vanilla js 替代 jquery 方法来执行安全的 html 解码?

Javascript 获取数组中最旧的元素

javascript - 在Ajax中,我想要有2个及更多的输入功能。我怎样才能做到这一点?