Найти, какая плитка была нажата в изометрической, шахматной системе столбцов
Моя сетка
tileWidth = 64px
tileHeight = 128px
(само изображение 128px, хотя фактический Алмаз 32px высотой и 64px шириной)
Как вы можете видеть, у меня есть шахматная сетка; однако я потратил последние два часа, пытаясь придумать систему, в которой я мог бы взять координаты мыши относительно холста и выяснить, какая плитка была нажата (очевидно, в пределах ромбовидного поля).Например, если я нажму tile 21, 26
- Как я буду вычислять это есть в программе?
Любые указатели, чтобы заставить работать в правильном направлении, будут высоко оценены. Спасибо!
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>