基于Swing的战舰游戏:鼠标捕获矩阵与文件矩阵倒置问题求助
看起来你遇到的问题是Swing坐标系和矩阵存储顺序不匹配导致的上下倒置,这在2D图形编程里是很常见的坑——毕竟Swing的原点在左上角,y轴是向下走的,而我们通常习惯的矩阵是从上到下计数行的。
我帮你梳理下问题所在,然后给出具体的修改方案:
首先,你的代码里有两个关键问题:
- 绘制时的坐标映射搞反了:你把矩阵的行索引(i)用作屏幕的x坐标,列索引(j)用作y坐标,这直接导致矩阵的行列在屏幕上被旋转,同时上下顺序也不对。
- 鼠标点击的坐标没有反转:Swing里鼠标的y坐标从顶部开始算,而你的矩阵行可能是从逻辑上的“顶部”开始存储的,所以需要反转y坐标才能匹配矩阵的索引。
接下来是具体的修改步骤:
1. 修正鼠标点击的坐标转换
在GameFrame的mouseReleased方法里,把y坐标转换为矩阵行索引时,需要反转,同时加上边界检查避免数组越界:
@Override public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY(); int x_pos = x / canvas.AREA; // 列索引,这个是对的 // 反转y坐标,将屏幕顶部的点击映射到矩阵的最后一行,底部映射到第一行 int y_pos = canvas.getRows() - 1 - (y / canvas.AREA); // 边界检查,防止点击窗口外导致数组越界 if (x_pos >= 0 && x_pos < canvas.getCols() && y_pos >= 0 && y_pos < canvas.getRows()) { System.out.println(canvas.getShot(x_pos, y_pos)); } }
2. 修正Canvas中的绘制坐标
在GameCanvas的paint方法里,调整绘制图像的x和y坐标,让矩阵的行对应屏幕的y轴,列对应x轴,同时反转行索引来匹配Swing的坐标系:
// 替换原来的绘制循环 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 计算屏幕上的y坐标:反转矩阵行索引,让矩阵第一行显示在屏幕顶部 int screenY = (rows - 1 - i) * AREA; // 屏幕上的x坐标:用列索引计算,对应水平位置 int screenX = j * AREA; g.drawImage(img, screenX, screenY, AREA, AREA, null); if (explosionMatrix[i][j] == 1) { g.drawImage(imgShot, screenX, screenY, AREA, AREA, null); } } }
3. 修正Canvas的大小设置
在GameCanvas的构造方法里,你之前搞反了宽度和高度的参数,需要改成:
public GameCanvas(ArcMap archive) { this.achive = archive; this.rows = archive.getArcHeight(); this.cols = archive.getArcWidth(); explosionMatrix = archive.getArcMatrix(); // 宽度是列数*AREA,高度是行数*AREA setSize(AREA * cols, AREA * rows); }
额外提个小建议:在Swing中重写paint方法时,最好先调用super.paint(g),确保组件的背景和默认绘制逻辑正常执行,避免出现绘制残留的问题。
这些修改完成后,你的矩阵绘制顺序就会和文件中的一致,鼠标点击的位置也会准确对应到矩阵的索引上,倒置的问题就解决了。
内容的提问来源于stack exchange,提问作者Ésio Gustavo Freitas
相关产品推荐
相关产品推荐

