# Array of map data renders the map the opposite way

A while ago by following some tutorials I made a game map array consisting of 0, 1 and 2. I program it the way I want to see it:

var mapArray = [
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
[0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
[0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];


So for example the line [0, 0, 0, 1, 1, 1, 1, 1, 0, 0] lies on the X axis and I want to see grass 1 horizontally, but when I draw it on the canvas it's being rendered vertically instead. So the y and x axis are being swapped in place. Why is this so? Here is the rendering code:

function render(viewport) {
context.save();
context.translate(view.x, view.y);
requestAnimationFrame(render);
var oldPosX = boatPosX;
var oldPosY = boatPosY;

for (let i = 0; i < mapArray.length; i++) {
for (let j = 0; j < mapArray[i].length; j++) {
if (mapArray[i][j] == 0) {
this.sprite.draw(
background,
190,
230,
26,
26,
i * this.sprite.width,
j * this.sprite.height,
this.sprite.width,
this.sprite.height
);
}
if (mapArray[i][j] == 1) {
this.sprite.draw(
background,
30,
30,
26,
26,
i * this.sprite.width,
j * this.sprite.height,
this.sprite.width,
this.sprite.height
);

}
if (mapArray[i][j] == 2) {
this.sprite.draw(
background,
200,
20,
26,
26,
i * this.sprite.width,
j * this.sprite.height,
this.sprite.width,
this.sprite.height
);
}
}
}
this.ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
var lineHeight = 16 * 2.286;
var textWidth = context.measureText(theArray[moveCount].question).width * 3;
context.textAlign = 'left';
context.textBaseline = 'top';
context.font="14px Verdana";
context.fillStyle = 'rgba(0, 0, 0 ,0.9)';
context.fillRect(boatPosX + ship.width / 2, boatPosY - ship.height / 2, textWidth, lineHeight);
context.fillStyle = 'white';
context.fillText(theArray[moveCount].question, boatPosX + ship.width / 2, boatPosY - ship.height / 2);

answerBtn1.innerHTML = theArray[moveCount].answer1;
answerBtn2.innerHTML = theArray[moveCount].answer2;
if(isPositionWall(boatPosX, boatPosY)) {
boatPosX = oldPosY;
console.log("collision");
}

context.restore();

};

• Because you swapped i and j for either drawing or indexing. – tkausl May 23 '18 at 15:18

## 1 Answer

You are using the index i to read horizontal values and j for vertical values, but the way you stored values is reversed. If you had a 2D array (a matrix) it'd work, however you defined an array whose elements are arrays themselves.

When you read mapArray[0] you get the array [0, 0, 0, 0, 1, 0, 0, 0, 0, 0] which is the first row of world tiles. Then, mapArray[1] will return the second row, and so on. So, mapArray[i] returns the i-th row of your tilemap, and it means you're using the index i to navigate through columns, not rows; though you're using the variable i the other way round. Same applies for variable j.

To quick fix it, just change the way you read mapArray: to access the element in i-th row, j-th column, you need to write mapArray[j][i].

### Edit #1

The quick fix is not ideal, since i and j aren't used to navigate the tilemap only but also to proper render sprites.

Then, you only need to reverse usage of i and j in loops, where they are used as coordinates of the map array. The new nested loop will look like this:

for (let j = 0; j < mapArray.length; j++) {
for (let i = 0; i < mapArray[j].length; i++) {
// draw
}
}


You may also use separate variables to store arrayMap sizes, and the code will look even more clear:

var W;
var H = mapArray.length;

for (let j = 0; j < H; j++) {
W = mapArray[j].length;
for (let i = 0; i < W; i++) {
// draw
}
}

• Thank you, it works now, but I have other problem. If I keep the code the way it was before, I can create the array map however I want. But if I swap it to mapArray[j][i] like you said, I keep getting script.js:113 Uncaught TypeError: Cannot read property '0' of undefined and the line 113 is this inside the render code I posted OP  if (mapArray[j][i] == 0) { Do you have any idea why this could be happening? If it deserves its own question, let me know, I will create another question dedicated to this error. – Limpuls May 23 '18 at 16:58
• So after some debugging I found out that I get this error if my mapArray has more members horizontally than vertically. If I have 15 members on each column then I have to have 15 or more rows otherwise I get the error. Can't think of any reason for this happening – Limpuls May 23 '18 at 17:17
• This may be due to spread usage of indexes i and j for rendering. I edited my answer to include an alternate solution. – liggiorgio May 24 '18 at 13:53