从鼠标侦听器中查找磁贴



我正在尝试利用MouseListenerinterface制作国际象棋游戏。(没有JButtons! 单击后,我能够在JFrame上找到单击的[x, y]位置,但我想找到磁贴。

棋盘是一个8 x 8的网格。磁贴是该网格上的一个位置(因此[1, 3]磁贴。

我的想法是将xPosition除以tileWidthyPosition除以tileHeight。我应该能够通过获取屏幕的大小并将其除以瓷砖数量来找到tileHeighttileWidth(这将始终8,因为棋盘8 x 8)

这在大多数情况下都有效,但是当我单击靠近每个磁贴的边缘时,上述等式的结果是不准确的。

/** 
* @param screen The JPanel that contains the tiles (Will always be the size of the entire board)
* @param pos The (x, y) position of the click
* @return The tile found from the click
*/
public Tile getTile(Screen screen, Pos pos) {
int x = (pos.x / (screen.getWidth() / Board.WIDTH)); // When trying to typecast to a double, then back to an int, the result become more inaccurate.
int y = (pos.y / (screen.getHeight() / Board.HEIGHT));
System.out.println(new Pos(x, y));
return tiles[y][x];
}

编辑:我的JPanelJContentPane(JFrame中的区域)的大小相同

编辑:我完全错了!

假设你的整个JPanel填满了你的整个JFrame,并且你的参数pos在 JPanel 和 JFrame 的左上角开始一个 [0,0],在右下角以它的最大维度结束,你的计算实际上是正确的:

假设你的 JPanel 和 JFrame 的宽度为 1000px,高度为 1000px。

让我们水平(左右)单击500px,这意味着在水平轴(X)的中间

Click
|
+
|1|2|3|4|5|6|7|8|

这将评估为:500/(1000/8) = 500/(125) = 4, 当我们说在第 4 列和第 5 列之间恰好单击将是对第 4 列的单击时,这是正确的,例如tiles[y][4-1];记住数组从 0 开始

当执行(499/(1000/8) = 499/(125) = 3,992时,当转换为 int 时,这将是 3(强制转换删除所有十进制数字),这是正确的。

当做(501/(1000/8) = 501/(125) = 4,008当转换为 int 时,它也将是 4。这也是正确的。

当屏幕的左侧 50% (499px) 时,您需要有 col 磁贴[y][3],而在屏幕右侧 50% 时,您需要有平铺[y][4]

这意味着您的计算是正确的。

我唯一能想到的是你得到了一个错误的鼠标位置,或者你的JFrame没有完全填满你的JPanel。

尝试在鼠标移动时打印出鼠标位置,然后检查是否全部正确

问题部分出在方程上。我应该坚持使用如下所示的类型转换:

int x = (int) (pos.x / ((double) screen.getWidth() / Board.WIDTH));
int y = (int) (pos.y / ((double) screen.getHeight() / Board.HEIGHT));

但真正的问题是MouseEventinterfaceJFRAME的左上角算作point[0, 0]。这意味着JCONTENTPANE的左上角实际上将位于point[~10, ~40](我之所以这么说,是因为该点可能因计算机而异,以及我个人能够单击JFrame的接近程度)。如果你想找到额外空间的确切值,得到JFrame的大小并减去JContentPane的大小。

int x = (int) ((pos.x - X_OFFSET) / ((double) screen.getWidth()  / Board.WIDTH));
int y = (int) ((pos.y - Y_OFFSET) / ((double) screen.getHeight() / Board.HEIGHT));

X_OFFSET = 8Y_OFFSET = 38的地方

最新更新