【问题标题】:How to transform mouse location in isometric tiling map?如何在等距平铺地图中转换鼠标位置?
【发布时间】:2011-08-02 16:46:12
【问题描述】:

所以我设法自己编写了第一部分(算法)来计算每个图块在绘制这张地图时应该放置的位置(见下文)。但是,我需要能够将鼠标位置转换为适当的单元格,而且我几乎把头发扯掉了,因为我不知道如何从鼠标位置获取单元格。我担心的是它涉及一些相当高的数学或一些我只是简单的东西我无法注意到的东西。
例如,如果鼠标位置是 112;35 我如何计算/转换它以使单元格在该位置是 2;3? 也许这里有一些非常优秀的具有数学思维的程序员会在这方面帮助我,或者知道如何做或者可以提供一些信息的人?

var cord:Point = new Point();
cord.x = (x - 1) * 28 + (y - 1) * 28;
cord.y = (y - 1) * 14 + (x - 1) * (- 14);

说到地图,每个单元格(透明平铺56x28像素)都放置在前一个单元格的中心(或单元格1;1的零位),上面是代码I用于将单元格转换为位置。我尝试了很多关于位置到单元格的方法和计算,但都失败了。

编辑: 在阅读了大量信息后似乎使用屏幕外颜色图(颜色映射到图块)是最快和最有效的解决方案?

【问题讨论】:

标签: algorithm math


【解决方案1】:

我知道这是一篇旧帖子,但我想更新它,因为有些人可能仍在寻找这个问题的答案,就像我今天早些时候一样。但是,我自己想通了。还有一种更好的渲染方法,这样您就不会遇到图块重叠的问题。

代码就这么简单:

mouse_grid_x = floor((mouse_y / tile_height) + (mouse_x / tile_width));
mouse_grid_y = floor((-mouse_x / tile_width) + (mouse_y / tile_height));

mouse_x 和 mouse_y 是鼠标屏幕坐标。

tile_height 和 tile_width 是实际的图块大小,而不是图像本身。正如您在我的示例图片中看到的那样,我在瓷砖下添加了污垢,这只是为了更容易渲染,实际尺寸为 24 x 12。坐标也是“地板”以保持结果网格 x 和 y 向下舍入。

还请注意,我从 y=0 和 x=tile_with / 2(红点)渲染这些图块。这意味着我的 0,0 实际上从瓷砖的顶角开始(倾斜),而不是在露天。将这些图块视为旋转的正方形,您仍然希望从 0,0 像素开始。

Tiles 将从 Y = 0 和 X = 0 开始渲染到地图大小。渲染第一行后,您向下和向左跳过几个像素。这将使下一行瓦片与第一行重叠,这是保持层重叠重叠的好方法。您应该先渲染图块,然后再渲染该图块上的任何内容,然后再继续下一个。

我也会添加一个渲染示例:

for (yy = 0; yy < map_height; yy++)
{
     for (xx = 0; xx < map_width; xx++)
     {
          draw tiles here with tile coordinates:
          tile_x = (xx * 12) - (yy * 12) - (tile_width / 2)
          tile_y = (yy * 6) + (xx * 6)

          also draw whatever is on this tile here before moving on
     }
}

【讨论】:

    【解决方案2】:
    (1) x` = 28x -28 + 28y -28  = 28x + 28y -56
    (2) y` = -14x +14 +14y -14 = -14x + 14y
    

    变换表:

    [x] [28  28 -56 ] = [x`]
    [y] [-14 14  0  ]   [y`]
    [1] [0    0  1  ]   [1 ]
    
    [28  28 -56 ] ^ -1 
    [-14 14  0  ]
    [0    0  1  ] 
    

    用绘图仪计算(我喜欢 wims)

    [1/56 -1/28  1 ]
    [1/56  1/28  1 ]
    [0      0    1 ]
    
    x = 1/56*x` - 1/28y` + 1
    y = 1/56*x` + 1/28y` + 1
    

    【讨论】:

    • en.wikipedia.org/wiki/Transformation_matrix ...两边,你得到 V*1=V`*A(-1)
    • 我要改造什么?整个地图图像使其基于矩形,然后轻松计算单元格?
    • 有没有办法用数学计算鼠标位置到单元格,而不必旋转地图图像?
    • @Yochai Timmer 不错的解决方案。不就是仿射变换吗?
    • 这样的转换也是像素精确的吗?以及在鼠标移动时进行这些转换的效率如何?
    【解决方案3】:

    我像上面那样渲染了瓷砖。

    解决方案非常简单!

    第一件事:

    我的 Tile 宽度和高度都是 = 32 这意味着在等轴测视图中, 宽度 = 32 高度 = 16! 本例中的 Mapheight 为 5(最大 Y 值)

    当 y_mouse=MapHeight/tilewidth/2 且 x_mouse = 0 时,y_iso & x_iso == 0

    当 x_mouse +=1,y_iso -=1

    所以首先我计算“每像素变换”

    TileY = ((y_mouse*2)-((MapHeight*tilewidth)/2)+x_mouse)/2;

    TileX = x_mouse-TileY;

    要找到我只是通过 tilewidth 划分的 tile 坐标

    TileY = TileY/32; TileX = TileX/32;

    完成!! 从来没有任何问题!

    【讨论】:

    • 感谢您,多年来一直在寻找解决方案!
    【解决方案4】:

    我在这个网站http://www.tonypa.pri.ee/tbw/tut18.html 上找到了算法。我无法让它为我正常工作,但我通过反复试验将其更改为此表单,它现在对我有效。

    int x = mouse.x + offset.x - tile[0;0].x; //tile[0;0].x is the value of x form witch map was drawn
    int y = mouse.y + offset.y;
    double _x =((2 * y + x) / 2);
    double _y= ((2 * y - x) / 2);
    double tileX = Math.round(_x / (tile.height - 1)) - 1;
    double tileY = Math.round(_y / (tile.height - 1));
    

    这是我的地图生成

    for(int x=0;x<max_X;x++)
    for(int y=0;y<max_Y;y++)
    map.drawImage(image, ((max_X - 1) * tile.width / 2) - ((tile.width - 1) / 2 * (y - x)), ((tile.height - 1) / 2) * (y + x));
    

    【讨论】:

      【解决方案5】:

      一种方法是将其旋转回方形投影:

      首先平移 y,使尺寸相对于原点:

       x0 = x_mouse;
       y0 = y_mouse-14
      

      然后按您的图块大小进行缩放:

       x1 = x/28;   //or maybe 56?
       y1 = y/28
      

      然后按投影角度旋转

       a = atan(2/1);   
       x_tile = x1 * cos(a) - y1 * sin(a);
       y_tile = y1 * cos(a) + x1 * sin(a);
      

      我可能遗漏了一个减号,但这是一般的想法。

      【讨论】:

      • 旋转回整个地图图像是吗?让它基于矩形?
      • 您实际上不必旋转整个地图。只需将旋转应用到鼠标位置,您就可以获得坐标中的等效位置,就好像地图已旋转一样。不过,我认为@yochai 的回答是一个更实际的解决方案。
      • 在@yochai 的示例中它是否也仅将旋转应用于鼠标位置?或不?因为我看不到如何倾斜或旋转鼠标位置,例如 (112,35)。
      【解决方案6】:

      尽管您在最初的问题中没有提到它,但在 cmets 中,我认为您说您是在 Flash 中编程的。在这种情况下,Flash 带有矩阵转换功能。在坐标系之间进行转换(例如到等轴坐标)的最可靠方法是使用矩阵变换:

      http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html

      您可能希望以与旋转和缩放图形的方式相反的方式旋转和缩放矩阵。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-28
        • 2013-08-08
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-08
        相关资源
        最近更新 更多