简体   繁体   中英

javascript how can I add additional properties to an array's coordinates inside of a loop, without erasing the existing properties of the array

I have narrowed down a bug in my program to the following.

The following loop works so long as maxlayout equals 1 but if it equals two thus making the loop run twice then the original values erase.

so if the loop is run once then mainArray.tilef0 will equal tile.empty but if tan twice then mainArray.tilef0 will be undefined and mainArray.tilef1 will equal tile.empty

The same is true for the rest of the properties such as terrain and solid.

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

Barmar and Henery Answered my question but I thought I would add the whole code below. So that they or others could see how it helped and/or help me or others to see if there is a better way such as maybe initializing the array before the point I needed help in.

So below is the functioning version with the code they assisted me with.

I apologize if it is messy, I struggle to keep code clean and don't know all the standard ways of doing things. But I added lots of comments.

 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>

If you want to test it I recommend running the snippet then clicking fullscreen Arrow keys to move , and . will change which floor is rendering.

Barmar's answer identifies the issue, but will very likely run into undefined error, if mainArray[i][j] is not initialized. So something like this:

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;
}

You're replacing the array element instead of adding new properties to it.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM