【问题标题】:Find which tile was clicked in a isometric, staggered column system查找在等距、交错列系统中单击了哪个图块
【发布时间】:2014-11-24 08:36:43
【问题描述】:

我的网格

tileWidth = 64px
tileHeight = 128px

(图像本身是 128 像素,而实际的菱形是 32 像素高和 64 像素宽)

如你所见,我有一个交错的网格系统;但是,我在过去的两个小时里一直在想一个系统,我可以在其中获取鼠标相对于画布的坐标,并确定点击了哪个图块(显然是在菱形字段内)。

例如,如果我点击了磁贴 21, 26 -- 我将如何在程序中解决这个问题?

任何指向正确方向工作的指针将不胜感激。谢谢!

【问题讨论】:

    标签: canvas html5-canvas 2d isometric


    【解决方案1】:

    如果您知道单元格的中心位置,您当然知道单元格的中心位置,因为它们已被渲染,您只需对单元格的坐标进行归一化即可确定它是否在内部:

    var dx = Math.abs(x - cellCenterX),
        dy = Math.abs(y - cellCenterY);
    
    if (dx / (cellWidth * 0.5) + dy / (cellHeight * 0.5) <= 1) { /* is inside */ };
    

    这是一个完整的演示:

    var cw = 64,
        ch = 32,
        cells = [],
        maxH = 10,
        maxV = 5,
        toggle = true,
        
        canvas = document.getElementById("canvas"),
        ctx = canvas.getContext('2d');
    
    // Using a cell object for convenience here:
    function Cell(posX, posY, x, y, w, h) {
      this.posX = posX;            // some id....
      this.posY = posY;            // some id....
      this.x = x;                  // cells top position
      this.y = y;
      this.w = w;                  // width and height of cell
      this.h = h;
      this.centerX = x + w * 0.5;  // abs. center of cell
      this.centerY = y + h * 0.5;
    }
    
    // draw this cell:
    Cell.prototype.render = function(ctx, color) {
      ctx.beginPath();
      ctx.moveTo(this.centerX, this.y);
      ctx.lineTo(this.x + this.w, this.centerY);
      ctx.lineTo(this.centerX, this.y+this.h);
      ctx.lineTo(this.x, this.centerY);
      ctx.closePath();
      ctx.fillStyle = color;
      ctx.fill();
      ctx.strokeStyle = "#000";
      ctx.stroke();
    };
    
    // check if x/y is inside this cell
    Cell.prototype.isInCell = function(x, y) {
    
      var dx = Math.abs(x - this.centerX),
          dy = Math.abs(y - this.centerY);
    
      return (dx / (this.w * 0.5) + dy / (this.h * 0.5) <= 1);
    };
    
    // generate cell map
    for(var y = 0; y < maxV; y++) {
      var dltX = toggle ? 0 : -cw * 0.5,
          dltY = -ch * 0.5 * y;
      
      toggle = !toggle;
      
      for(var x = 0; x < maxH; x++) {
          var c = new Cell(x, y, x * cw + dltX, y * ch + dltY, cw, ch);
          cells.push(c);
          c.render(ctx, "#9f0"); // green bg
      }
    }
    
    // test by clicking in cell
    canvas.onclick = function(e) {
      
      var r = canvas.getBoundingClientRect(),
          x = e.clientX - r.left,
          y = e.clientY - r.top,
          i = 0, cell;
      
      for(; cell = cells[i]; i++) {
        if (cell.isInCell(x, y)) {
          cell.render(ctx, "#f00"); // red bg if inside
          out.innerHTML = "Cell pos: (" + cell.posX + "," + cell.posY + ") X: " + cell.x + " Y: " + cell.y;
          break;
        }
      }
    };
    <canvas id=canvas width=500 height=100></canvas><br>
    <output id=out></output>

    【讨论】:

    • 太棒了,帮了大忙!谢谢!
    • 你有没有考虑过y = Math.acos(Math.cos(x))更有效的方法来获取偏移量,并确定tileX/tileY的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2014-07-15
    • 1970-01-01
    • 2018-04-27
    • 2016-08-30
    • 2012-03-01
    • 1970-01-01
    相关资源
    最近更新 更多