Search code examples
javascripthtml5-canvasjstilemap

How can I fix my tilemap being flipped from the array it's generated from?


I'm trying to render a tilemap in a game that I'm working on, but when rendering it's flipped both vertically and horizontally. I'm working on it in the HTML 5 Canvas using JavaScript. I've tried everything I can think of, but I can't seem to get rid of the issue.

Index JS:

import Map from './MapClass.js';

export var miniMapScale = .5;

var MiniMap = document.createElement("canvas");
document.body.appendChild(MiniMap);
MiniMap.width = miniMapScale * 640;
MiniMap.height = miniMapScale * 640;
MiniMap.id = "TopDownView";
var ctx = MiniMap.getContext("2d");

var TestMap = new Map([
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,1,0,0,0,0,0,0,1],
    [1,0,1,0,0,0,0,0,0,1],
    [1,0,1,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,1],
    [1,0,0,0,0,0,1,1,1,1],
    [1,0,0,0,0,0,0,0,0,1],
    [1,0,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]

]);

function drawTopDownMap() {
    ctx.clearRect(0, 0, MiniMap.width, MiniMap.height);

    TestMap.draw();

    requestAnimationFrame(drawTopDownMap);
};

requestAnimationFrame(drawTopDownMap);

Map Class JS:

import { miniMapScale } from './index.js';

export default class Map{
    constructor(mapData) {
        this.data = mapData;
        this.tileSize = miniMapScale * 64;
        this.width = this.data[0].length;
        this.height = this.data.length;
        this.ctx = document.getElementById("TopDownView").getContext("2d");
    };

    draw() {
        for(var y = 0; y < this.height; y++) {
            for(var x = 0; x < this.width; x++) {
                var wall = this.data[x][y];

                if(wall == 0) {
                    this.ctx.fillStyle = "#ffe4c4";

                    this.ctx.fillRect(
                        x * this.tileSize,
                        y * this.tileSize,
                        this.tileSize, this.tileSize
                    );
                }else if(wall == 1) {
                    this.ctx.fillStyle = "#000000";

                    this.ctx.fillRect(
                        x * this.tileSize,
                        y * this.tileSize,
                        this.tileSize, this.tileSize
                    );
                };
            };
        }
    }
};

Any help would be greatly appreciated!


Solution

  • Your 2D array has Y as the first dimension and X as the second dimension. This is because your data is arranged as an array of rows, not an array of columns.

    Using this.data[y][x] should provide the expected result.

    draw() {
        for(var y = 0; y < this.height; y++) {
            for(var x = 0; x < this.width; x++) {
                var wall = this.data[y][x]; // instead of [x][y]
    
                if(wall == 0) {
                    this.ctx.fillStyle = "#ffe4c4";
                } else if(wall == 1) {
                    this.ctx.fillStyle = "#000000";
                }
    
                // Moved this out of the if statement to avoid repeated code
                this.ctx.fillRect(
                    x * this.tileSize,
                    y * this.tileSize,
                    this.tileSize, this.tileSize
                );
            }
        }
    }
    

    Here's a working snippet:

    var miniMapScale = 0.5;
    
    class Map {
      constructor(mapData) {
        this.data = mapData;
        this.tileSize = miniMapScale * 64;
        this.width = this.data[0].length;
        this.height = this.data.length;
        this.ctx = document.getElementById('TopDownView').getContext('2d');
      }
    
      draw() {
        for (var y = 0; y < this.height; y++) {
          for (var x = 0; x < this.width; x++) {
            var wall = this.data[y][x];
    
            if (wall == 0) {
              this.ctx.fillStyle = '#ffe4c4';
            } else if (wall == 1) {
              this.ctx.fillStyle = '#000000';
            }
            this.ctx.fillRect(
              x * this.tileSize,
              y * this.tileSize,
              this.tileSize,
              this.tileSize
            );
          }
        }
      }
    }
    
    var MiniMap = document.createElement('canvas');
    console.log(document);
    document.body.appendChild(MiniMap);
    MiniMap.width = miniMapScale * 640;
    MiniMap.height = miniMapScale * 640;
    MiniMap.id = 'TopDownView';
    var ctx = MiniMap.getContext('2d');
    
    var TestMap = new Map([
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      [1, 0, 1, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 1, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 1, 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, 1],
      [1, 0, 0, 0, 0, 0, 1, 1, 1, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ]);
    
    function drawTopDownMap() {
      ctx.clearRect(0, 0, MiniMap.width, MiniMap.height);
    
      TestMap.draw();
    
      requestAnimationFrame(drawTopDownMap);
    }
    
    requestAnimationFrame(drawTopDownMap);