自学内容网 自学内容网

棋子坐标转换

在基于网格的游戏或应用中,棋子坐标转换是一个重要的知识点,它涉及如何将屏幕上的像素坐标(例如,鼠标点击的坐标)转换为逻辑坐标(例如,棋盘中的行列号),并确保棋子能够准确地放置在棋盘上。以下是相关的知识点及其讲解:

1. 像素坐标与逻辑坐标

  • 像素坐标是指屏幕上的具体位置,用像素值表示,比如鼠标点击的 (x, y) 坐标。
  • 逻辑坐标是指游戏中的抽象坐标系统,如棋盘的行列号 (row, col)。这表示棋盘上每个格子的编号,例如 15x15 棋盘有 15 行 15 列。

转换目标:将用户点击屏幕的 像素坐标 转换成棋盘的 逻辑坐标(行列号),再通过逻辑坐标计算出棋子应该绘制的位置。

2. 棋盘的几何结构

  • 棋盘通常被看作一个二维网格,由多个格子组成。
  • 每个格子大小一致,通常用 cellSize 来表示。
  • 棋盘有边距 (padding),棋盘的绘制区域和实际屏幕位置不完全重合,棋盘左上角的起点并非 (0, 0),而是 (padding, padding)

公式概述

  • 棋盘上的逻辑行列 (row, col) 对应的像素坐标是通过棋盘左上角的起点和每个格子的大小来计算的。

3. 像素坐标到行列号的转换

为了将像素坐标转换为棋盘的行列号,需要:

  1. 减去棋盘的边距padding),因为棋盘的左上角并不在屏幕的 (0, 0) 位置。
  2. 除以每个格子的大小cellSize),来计算鼠标点击的具体行列。

公式:

row = (y - padding) / cellSize
col = (x - padding) / cellSize

其中,xy 是鼠标点击的屏幕像素坐标,padding 是棋盘的边距,cellSize 是每个格子的大小。

四舍五入

  • 由于点击的位置不会总是刚好落在格子的中心,所以我们可以通过 四舍五入 将点击的位置对齐到最近的棋盘交点:
    row = Math.round((float)(y - padding) / cellSize);
    col = Math.round((float)(x - padding) / cellSize);
    

4. 行列号到棋子像素位置的转换

计算出棋盘的逻辑行列后,需要将棋子绘制在对应格子的中心。棋子的中心应该对齐到网格的交点。

计算棋子中心位置

  1. 棋子的 X 坐标:

    xPos = padding + col * cellSize - chessRadius
    

    其中 chessRadius 是棋子半径,通过这个公式,我们得到棋子左上角的 X 坐标。

  2. 棋子的 Y 坐标:

    yPos = padding + row * cellSize - chessRadius
    

最后,通过绘制椭圆(fillOval)来将棋子画在指定位置:

g.fillOval(xPos, yPos, chessRadius * 2, chessRadius * 2);

5. 有效区域判断

当计算出行列号后,确保行列号在棋盘的有效范围内:

if (row >= 0 && row < gridSize && col >= 0 && col < gridSize) {
    // 合法位置,进行绘制
}

6. 总结流程

  • 鼠标点击时
    1. 通过鼠标事件得到点击的 (x, y) 像素坐标。
    2. 使用公式计算出点击对应的棋盘逻辑坐标 (row, col)
    3. 判断是否在合法的棋盘范围内。
    4. 将棋盘的逻辑坐标转换为棋子在屏幕上的具体像素坐标 (xPos, yPos)
    5. 绘制棋子。

7. 代码中应用

Play() 方法中,通过鼠标点击事件得到的坐标 xy,我们使用前述公式转换为棋盘行列号,并进行判断与绘制:

private void Play(MouseEvent e) {
    int x = e.getX();
    int y = e.getY();

    // 获取棋盘的边距和格子大小
    int padding = gamePanel.getPadding();
    int cellSize = gamePanel.getCellSize();

    // 计算点击的行列号,使用四舍五入
    int row = Math.round((float)(y - padding) / cellSize);
    int col = Math.round((float)(x - padding) / cellSize);

    // 判断是否在棋盘范围内
    if (row >= 0 && row < gamePanel.getGridSize() && col >= 0 && col < gamePanel.getGridSize()) {
        // 在有效区域内,添加棋子
        gamePanel.addChess(new GameChessPieces(row, col, 1));
    }
}

通过以上知识点的掌握,你可以轻松处理棋子定位、绘制等相关操作。


原文地址:https://blog.csdn.net/2301_79271343/article/details/142686054

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!