找到这片被点击一个等距,交错塔系统 [英] Find which tile was clicked in a isometric, staggered column system

查看:196
本文介绍了找到这片被点击一个等距,交错塔系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的网格

  tileWidth = 64PX
tileHeight = 128像素
 

(图像本身是128像素,虽然实际钻的是32PX高大64PX宽)

正如你所看到的,我有一个交错的网格系统;不过,我已经花了近两年时间试图想一个系统,我可以把鼠标的坐标相对于画布上,并找出原因的瓷砖被点击(显然是在一个菱形场)。

例如,如果我点击瓷砖 21,26 - ?我怎么会明白这一点,在节目

任何指针,以获得正确的方向前进是会大大AP preciated。谢谢!

解决方案

如果您知道单元,这当然你这样做,因为它们呈现的中心位置,只需规范化协调打击细胞,以找出是否是就在里面:

 变种DX = Math.abs(X  -  cellCenterX)
    DY = Math.abs(Y  -  cellCenterY);

如果(DX /(cellWidth * 0.5)+ DY /(cellHeight * 0.5)其中; = 1){/ *为内* /};
 

下面是一个完整的演示:

变种CW = 64,     CH = 32,     细胞= [],     maxH = 10,     MAXV = 5,     切换=真,          帆布=的document.getElementById(画布),     CTX = canvas.getContext('二维'); //使用的方便这里单元对象: 功能单元(POSX,POSY,X,Y,W,H){   this.posX = POSX; //一些ID ....   this.posY =波西; //一些ID ....   this.x = X; //细胞榜首位置   this.y = Y;   this.w = W; //宽度和细胞的高度   this.h = H;   this.centerX = X + W * 0.5; //腹肌。小区的中心   this.centerY = Y + H * 0.5; } //得出这样的细胞: Cell.pr​​ototype.render =功能(CTX,颜色){   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 =颜色;   ctx.fill();   ctx.strokeStyle =#000;   ctx.stroke(); }; //检查是否X / Y是该小区内 Cell.pr​​ototype.isInCell =功能(X,Y){   变种DX = Math.abs(X - this.centerX)       DY = Math.abs(Y - this.centerY);   返回(DX /(this.w * 0.5)+ DY /(this.h * 0.5)其中; = 1); }; //生成细胞图 为(变种Y = 0; Y< MAXV; Y ++){   VAR DLTX =切换? 0:-cw * 0.5,       dltY = -CH * 0.5 * Y;      !拨动=切换;      为(变种X = 0 X - 其中; maxH; X ++){       变种C =新的细胞(X,Y,X * CW + DLTX,Y * CH + dltY,CW,CH);       cells.push(C);       c.render(CTX,#9f0); //绿色BG   } } //通过点击电池测试 canvas.onclick =功能(E){      变种R = canvas.getBoundingClientRect(),       X = e.clientX - r.left,       Y = e.clientY - r.top,       I = 0,细胞;      对于(;电池=细胞[我];我++){     如果(cell.isInCell(X,Y)){       cell.render(CTX,#F00);如果里面//红色BG       out.innerHTML =细胞POS:(+ cell.posX +,+ cell.posY +)X:+ cell.x +Y:+ cell.y;       打破;     }   } };

<帆布ID =画布宽度= 500高度= 100>< /帆布&GT ;< BR> <输出ID = OUT>< /输出>

My grid

tileWidth = 64px
tileHeight = 128px

(the image itself is 128px, though the actual diamond is 32px tall and 64px wide)

As you can see, I have a staggered grid system; however, I have spent the last two hours trying to think of a system where I can take the mouse coordinates relative to the canvas and figure out why tile was clicked (obviously within a diamond-shaped field).

For example, if I clicked tile 21, 26 -- how would I figure that out in the program?

Any pointers to get working in the right direction would be greatly appreciated. Thanks!

解决方案

If you know the center position of the cell, which of course you do since they are rendered, you simply normalize the coordinate against the cell to find out if it is inside:

var dx = Math.abs(x - cellCenterX),
    dy = Math.abs(y - cellCenterY);

if (dx / (cellWidth * 0.5) + dy / (cellHeight * 0.5) <= 1) { /* is inside */ };

Here is a full demo:

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>

这篇关于找到这片被点击一个等距,交错塔系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆