1
\$\begingroup\$

Following my old question Array of map data renders the map the opposite way after I got the answer to it and fixed my problem, I got another problem that occurs. If my mapArray[] is bigger on X axis than Y axis, I get

script.js:113 Uncaught TypeError: Cannot read property '0' of undefined

So if my array looks like this, for example:

[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],

I get an error. If I change it to this:

[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],
[2, 2, 2, 2, 2, 2,],

(more values vertically) it works fine. I know that it has to do with my loop condition:

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

j < mapArray[i].length this is not true if j is bigger than i length. Makes sense. But if I change the comparison < value to > I don't get drawn on the canvas anything but the white bg only.

My question: How can I have a big mapArray horizontally so that I could scroll it and have big game world without making it huge on the y axis as well?

Code:

var mapArray = [
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  [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, 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],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];

function render(viewport) {
  context.save();
  if(Math.floor(boatPosX / 36) < 10) {
    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[j][i] == 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[j][i] == 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[j][i] == 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);

  if(isPositionWall(boatPosX + 36, boatPosY)) {
    //boatPosX = oldPosY;
    console.log("collision");
  }
  context.restore();

};

I know what's causing the problem (the loop) but not sure how to fix it properly.

\$\endgroup\$
1
\$\begingroup\$

Inside your for loop, you need to index mapArray first by i, and then by j. You are doing this correctly in the loop condition, but inside the loop you use the indices in the wrong order.

So if-statements like these:

if (mapArray[j][i] == 0)

need to be changed to

if (mapArray[i][j] == 0)
\$\endgroup\$
  • \$\begingroup\$ But then my array is being rendered in the opposite way. Read my old question I have linked in OP. That was the reason to switch i j in places. So how should I approach this? Just deal with it being the opposite way? Because now I want to see the array being rendered the way it is coded in the file, f.e [0, 1, 0] meaning water on the left and right sides and ground in the middle. Not water on top and bottom. \$\endgroup\$ – Limpuls May 24 '18 at 12:39
  • \$\begingroup\$ Then you'll also need to simply swap the indices when you calculate positions for the tiles, i.e. i * this.sprite.width needs to become j * this.sprite.width. You are creating confusion for yourself by naming the indices i and j. It would be much clearer for you if you named them properly, i being y and j being x. \$\endgroup\$ – Tyyppi_77 May 24 '18 at 13:06

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.