所以我正在为html5中的canvas元素编写一个小的迷你伪3d引擎。在下面的代码中,我绘制了一堆具有不同位置和旋转的正方形(围绕z轴旋转,因此没有变形)
现在我希望能够告诉用户点击哪个方格。在对象数组中,项目由z位置支持,从距离摄像机最远的方块开始(以便它们正确绘制)。因此,如果相对于画布角的左上角有一个3d点,我怎么知道哪个方块被点击了?
//Draw objects
for (var i = 0; i < objects.length; i++) {
var object = objects[i];
var cz = object.position.z - camera.position.z;
if (cz > 0) {
cz = 1 / ((cz - 1) * 0.75 + 1);
context.save();
context.translate(halfWidth, halfHeight); //viewport transform
context.scale(1, -1); //invert y axis
context.scale(cz, cz); //perspective
context.translate(-camera.position.x, -camera.position.y); //camera transform
context.translate(object.position.x, object.position.y); //world transform
context.rotate(object.rotation);
context.fillStyle = object.color;
context.fillRect(-40, -40, 80, 80);
context.restore();
}
}
P.S。如果我做任何奇怪或倒退的事情并且你知道改进的方法,我很乐意听取建议
答案 0 :(得分:0)
我建议您将具有相同转换的对象绘制到相同大小的隐藏画布,但为每个方块赋予唯一的颜色(可能来自索引i
)。
你会这样做:
var col = index.toString(16); // convert to hex
while (col.length < 6) col = "0"+col; // pad leading 0s
ctx.fillStyle = "#"+col;
ctx.fillRect(-40,-40,80,80);
然后,当您在可见画布上获得鼠标点击事件时,请在隐藏的画布中查看该位置以获取所选对象的颜色(索引):
var colData = ctx.getImageData(clickX, clickY, 1, 1).data;
var index = (colData[2]<<16) | (colData[1]<<8) | colData[0];
这适用于多达16M的对象,非常简单。