如何计算等距世界中鼠标下方的图块索引,同时考虑图块高程 [英] How to calculate the index of the tile underneath the mouse in an isometric world taking into account tile elevation

查看:96
本文介绍了如何计算等距世界中鼠标下方的图块索引,同时考虑图块高程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于图块的等距世界,我可以使用以下计算来计算特定(鼠标)坐标下面的哪个图块:

  function isoTo2D(pt:Point):Point {
var tempPt:Point = new Point(0,0);
tempPt.x =(2 * pt.y + pt.x)/ 2;
tempPt.y =(2 * pt.y - pt.x)/ 2;
return(tempPt);
}

函数getTileCoordinates(pt:Point,tileHeight:Number):Point {
var tempPt:Point = new Point(0,0);
tempPt.x = Math.floor(pt.x / tileHeight);
tempPt.y = Math.floor(pt.y / tileHeight);
return(tempPt);
}

(摘自





在这些情况下,由于某些瓷砖的高度较高,后面的瓷砖(或瓷砖的一部分)会被遮盖,不应该能够被选中鼠标,而是选择它前面的瓷砖。
如何在考虑瓷砖高度的情况下通过鼠标坐标计算瓷砖?



我正在使用javascript和canvas实现。

解决方案

有一种技术可以在画布上捕捉鼠标下的对象而无需将鼠标坐标重新计算到世界坐标中。这不是完美的,有一些缺点和限制,但在一些简单的情况下它确实起作用。



1)放置另一个画布在您的主画布的顶部并将其不透明度设置为0.确保您的第二个 canvas 具有相同的大小并与您的主要重叠。



2)每当您将交互式对象绘制到主<$ c $时c> canvas ,在第二个画布上绘制并填充相同的对象,但每个对象使用一种唯一的颜色(从#000000 #ffffff



3)将鼠标事件处理设置为第二个画布。



4)在鼠标位置的第二个画布上使用 getPixel 来获取对象的id点击/悬停在上面。



主要优势是 WYSIWYG 原则,所以(如果一切正常)你可以成为当然,主画布上的对象与第二个上的对象相同canvas ,因此您无需担心画布调整大小或对象深度(如您的情况)计算以获得正确的对象。



主要缺点是需要双重渲染整个场景,但可以通过在不需要时不在第二个画布上进行优化,例如:




  • 处于空闲场景状态,当交互式对象停留在他们的位置并等待用户操作时。


  • 处于锁定场景状态,当某些内容是动画或smth时。并且不允许用户与对象进行交互。




主要限制是场景中交互式对象的最大数量(最高 #ffffff 或16777215个对象)。



所以......不推荐:




  • 场景中包含大量交互式对象的游戏。 (性能不佳)


  • 快节奏的游戏,不断移动/创建/销毁交互式对象。(性能不佳,重新使用id的问题)




适用于:




  • GUI的处理


  • 回合制游戏/慢节奏益智游戏。



I have a tile-based isometric world and I can calculate which tile is underneath specific (mouse) coordinates by using the following calculations:

function isoTo2D(pt:Point):Point{
  var tempPt:Point = new Point(0, 0);
  tempPt.x = (2 * pt.y + pt.x) / 2;
  tempPt.y = (2 * pt.y - pt.x) / 2;
  return(tempPt);
}

function getTileCoordinates(pt:Point, tileHeight:Number):Point{
  var tempPt:Point = new Point(0, 0);
  tempPt.x = Math.floor(pt.x / tileHeight);
  tempPt.y = Math.floor(pt.y / tileHeight);
  return(tempPt);
}

(Taken from http://gamedevelopment.tutsplus.com/tutorials/creating-isometric-worlds-a-primer-for-game-developers--gamedev-6511, this is a flash implementation but the maths is the same)

However, my problem comes in when I have tiles that have different elevation levels:

In these scenarios, due to the height of some tiles which have a higher elevation, the tiles (or portions of tiles) behind are covered up and shouldn't be able to be selected by the mouse, instead selecting the tile which is in front of it. How can I calculate the tile by mouse coordinates taking into account the tiles' elevation?

I'm using a javascript and canvas implementation.

解决方案

There is a technique of capturing object under the mouse on a canvas without needing to recalculate mouse coordinates into your "world" coordinates. This is not perfect, has some drawbacks and restrictions, yet it does it's job in some simple cases.

1) Position another canvas atop of your main canvas and set it's opacity to 0. Make sure your second canvas has the same size and overlaps your main one.

2) Whenever you draw your interactive objects to the main canvas, draw and fill the same objects on the second canvas, but using one unique color per object (from #000000 to #ffffff)

3) Set mouse event handling to the second canvas.

4) Use getPixel on the second canvas at mouse position to get the "id" of the object clicked/hovered over.

Main advantage is WYSIWYG principle, so (if everything is done properly) you can be sure, that objects on the main canvas are in the same place as on the second canvas, so you don't need to worry about canvas resizing or object depth (like in your case) calculations to get the right object.

Main drawback is need to "double-render" the whole scene, yet it can be optimized by not drawing on the second canvas when it's not necessary, like:

  • in "idling" scene state, when interactive objects are staying on their places and wait for user action.

  • in "locked" scene state, when some stuff is animated or smth. and user is not allowed to interact with objects.

Main restriction is a maximum number of interactive objects on the scene (up to #ffffff or 16777215 objects).

So... Not reccomended for:

  • Games with big amount of interactive objects on a scene. (bad performance)

  • Fast-paced games, where interactive objects are constantly moved/created/destroyed.(bad performance, issues with re-using id's)

Good for:

  • GUI's handling

  • Turn-based games / slow-paced puzzle games.

这篇关于如何计算等距世界中鼠标下方的图块索引,同时考虑图块高程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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