You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame网格坐标偏移问题:分数/像素级调整需求

解决方案:修正Pygame棋盘鼠标坐标偏移问题

核心问题原因

你绘制棋盘时给每个方块的Y坐标加了15像素偏移,但鼠标点击处理时未对应调整坐标,导致屏幕坐标与棋盘行号映射错位——屏幕Y=100的位置对应棋盘行0的底部(Y=115),但直接用event.pos[1]//100会把Y=85~115的区域判定为行1,这就是点击方块底部15像素会识别成下方方块的原因。

可行解决方法

1. 偏移鼠标坐标(推荐)

无需修改Pygame全局坐标,只需在处理鼠标点击时,将屏幕Y坐标先减去棋盘的15像素偏移量,再计算行号:

if event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
    x_coor = event.pos[0] // 100 - 3
    # 先减去棋盘Y偏移量,再计算行号
    y_coor = (event.pos[1] - 15) // 100 
    clk_coor = (x_coor, y_coor)

2. 浮点运算修正(不推荐但可行)

如果想用小数调整,可先做浮点除法再取整,本质和上面的方法一致:

y_coor = int((event.pos[1] / 100) - 0.15)

但这种方式不如直接减偏移量直观,易出错。

优化建议:用常量管理偏移量

将棋盘的偏移量定义为全局常量,绘制和鼠标处理统一使用,后续修改更方便:

# 全局常量定义
BOARD_Y_OFFSET = 15
BOARD_X_START = 300  # 从代码X计算逻辑反推,棋盘X起始位置为300

def Draw_Board():
    for i in range(blocks // 2):
        column = i % 4
        row = i // 4

        if row % 2 == 0:
            pg.draw.rect(screen, 'cadetblue', [900 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])
        else:
            pg.draw.rect(screen, 'cadetblue', [1000 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])

        if (row + 1) % 2 == 0:
            pg.draw.rect(screen, 'silver', [900 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])
        else:
            pg.draw.rect(screen, 'silver', [1000 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])

# 鼠标处理部分
if event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
    x_coor = (event.pos[0] - BOARD_X_START) // 100
    y_coor = (event.pos[1] - BOARD_Y_OFFSET) // 100
    clk_coor = (x_coor, y_coor)

完整修改后的关键代码片段

import pygame as pg

pg.init()

width = 1500
height = 1000
screen = pg.display.set_mode([width, height])
pg.display.set_caption("Play Chess")
font = pg.font.Font("freesansbold.ttf", 20)
big_font = pg.font.Font("freesansbold.ttf", 50)
timer = pg.time.Clock()
fps = 60
blocks = 8 ** 2
turn_select = 0
selection = 100
valid_moves = []
# 新增常量管理棋盘位置
BOARD_Y_OFFSET = 15
BOARD_X_START = 300

def Draw_Board():
    for i in range(blocks // 2):
        column = i % 4
        row = i // 4

        if row % 2 == 0:
            pg.draw.rect(screen, 'cadetblue', [900 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])
        else:
            pg.draw.rect(screen, 'cadetblue', [1000 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])

        if (row + 1) % 2 == 0:
            pg.draw.rect(screen, 'silver', [900 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])
        else:
            pg.draw.rect(screen, 'silver', [1000 - (column * 200), (row * 100) + BOARD_Y_OFFSET, 100, 100])


running = True
while running:
    timer.tick(fps)
    screen.fill("darkgreen")

    Draw_Board()
    if turn_select < 2:
        if selection < 2:
                pg.draw.rect(
                    screen, 'red', 
                    [white_loc[i][0] * 100 + BOARD_X_START, 
                        white_loc[i][1] * 100 + BOARD_Y_OFFSET + 1, 99, 99], 1)
    
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False

        if event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
            # 修正坐标计算
            x_coor = (event.pos[0] - BOARD_X_START) // 100
            y_coor = (event.pos[1] - BOARD_Y_OFFSET) // 100 
            
            clk_coor = (x_coor, y_coor)

            # 白方逻辑
            if turn_select < 2:
                if clk_coor in white_loc:
                    selection = white_loc.index(clk_coor)
                    if turn_select == 0:
                        turn_select = 1
                if clk_coor in valid_moves and selection != 100:
                    white_loc[selection] = clk_coor
                    if clk_coor in black_loc:
                        black_piece = black_loc.index(clk_coor)
                        captured_white.append(black_pieces[black_piece])
                        black_pieces.pop(black_piece)
                        black_loc.pop(black_piece)
                    
                    black_ops = check_ops(black_pieces, black_loc, 'black')
                    white_ops = check_ops(white_pieces, white_loc, 'white')
                    turn_select = 2
                    selection = 100
                    valid_moves = []

    pg.display.flip()
pg.quit()

内容的提问来源于stack exchange,提问作者Nathan Kamprath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:32:09