如何在 canvas 上的网格上的两点之间绘制瓷砖墙?

How to draw a tiled wall between two points on a grid on canvas?

我正在使用 Pixijs 引擎创建一个模拟器。

我有一个功能,就是用鼠标画墙。但我似乎做对了。这可能更像是一个数学问题而不是编程问题。

无论如何,它应该是这样工作的:

请看看这个Fiddle。 https://jsfiddle.net/ensf32e0/18/

我可以让它从左到右、从上到下绘制。但是从右到左和从下到上让我失望了。 我正在使用一个带有布尔值的对象来跟踪用户是放下开始位置还是结束位置。我不确定这是一个好的实现。

let wallsObj={
  start:{
    x:0,
    y:0,
    done:false
  },
  end:{
    x:1,
    y:1,
    done:false
  }
};

drawTile 绘制单个图块,而 drawWallLine 是有问题的函数。它采用开始和结束位置并在它们之间绘制一条平铺线:

function drawWallLine (obj,size) {
    // Determine whether line is to be drawn horizontally or vertically
    // if abs(x2-x1) is larger than abs(y2-y1) then horizontal else vertical
    // assign len the the actual length of line
    let len = Math.abs(obj.end.x - obj.start.x) > Math.abs(obj.end.y - obj.start.y)
        ? obj.end.x - obj.start.x
        : obj.end.y - obj.start.y;
        console.log('drawWallLine', len);

        // same as above. If direction is horizontal, mx = 1 and my = 0 and vice versa
        // this to be used to determine the polarity of size
        let mx = Math.abs(obj.end.x - obj.start.x) > Math.abs(obj.end.y - obj.start.y) ? 1 : 0;
        let my = Math.abs(obj.end.x - obj.start.x) < Math.abs(obj.end.y - obj.start.y) ? 1 : 0;
        console.log("mx, my", mx, my);

        // Get polarity of size. +size is going down or right while -size is going up or left
        if (mx === 1) {
            size = obj.end.x - obj.start.x >= 0 ? size : size * -1;
        }
        if (my === 1) {
            size = obj.end.y- obj.start.y >= 0 ? size : size * -1;
        }

        console.log('size', size);

        // If going down or right then 
        if (size >=0 ) {
            for (let i = 0; i < Math.abs(len); i+=size) {
                drawTile({
                    len: rs,
                    x: obj.start.x - obj.start.x%rs - .5 + i * mx,
                    y: obj.start.y - obj.start.y%rs - .5 + i * my,
                    line:{
                        width:1,
                        color:0xC2C2C2,
                        alpha:1
                    },
                    fill:{
                        color:0xFFFFFF,
                        alpha:1
                    }
                });
            }
        } else { // if going up or left
            for (let i = Math.abs(len); i > 0; i+=size) {
                drawTile({
                    len: rs,
                    x: obj.start.x - obj.start.x%rs - .5 + i * mx,
                    y: obj.start.y - obj.start.y%rs - .5 + i * my,
                    line:{
                        width:1,
                        color:0xC2C2C2,
                        alpha:1
                    },
                    fill:{
                        color:0xFFFFFF,
                        alpha:1
                    }
                });
            }
        }

}

这是我第一次做这样的事情,所以请多多包涵。我觉得有一个明显的解决方案,但我没有看到它。

好吧,解决您的问题的一个简单方法就是确保开始 x/y 始终低于结束 x/y 值。所以我在 drawWallLine 函数的开头添加了以下代码:

function drawWallLine (obj, size) {

    if(obj.start.x > obj.end.x){
        var temp = obj.start.x;
      obj.start.x = obj.end.x;
      obj.end.x = temp;
    }

    if(obj.start.y > obj.end.y){
        var temp = obj.start.y;
      obj.start.y = obj.end.y;
      obj.end.y = temp;
    }

这基本上通过在 startend if 之间交换来确保起始值始终是较低的值start 大于 end.

这是更新后的工作 fiddle:https://jsfiddle.net/ensf32e0/24/