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
相关产品推荐
相关产品推荐

