棋子坐标转换

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

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));
    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值