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

如何检测点击绘制在Pygame独立Surface上的圆形?

问题分析与解决方案

嘿,我一眼就发现问题所在了!你把圆形绘制在独立Surface s 上后,这个圆形在主屏幕上的实际位置并不是你检测时用的 (20,20) —— 因为你把Surface s 通过 s_rect 定位到了屏幕中心((300,300) 为中心的100x100区域),所以圆形在主屏幕上的真实圆心坐标是 Surface的左上角坐标加上你在Surface内绘制的圆心偏移量。

具体原因

你在Surface s 内以 (20,20) 为圆心画了圆,但Surface s 被blit到屏幕的 s_rect 位置(s_rect 的左上角是 (250,250),因为100x100的Surface中心在(300,300)),所以圆形在主屏幕上的实际圆心是 (250+20, 250+20) = (270,270),而你的点击检测还是用 (20,20) 作为圆心,自然点不到啦!

两种解决方案

方案一:计算圆形在主屏幕的绝对坐标检测

直接把Surface的位置偏移加到圆心坐标上,用屏幕绝对位置做检测:

from pygame.locals import *
import pygame, sys, math
pygame.init()
screen = pygame.display.set_mode((640, 480))
s = pygame.Surface((100, 100))
s.fill((255, 0, 0))
s_rect = s.get_rect(center = (300, 300))
# 提前计算Surface内圆形在屏幕上的绝对圆心
circle_center_screen = (s_rect.left + 20, s_rect.top + 20)
running = True
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            # 直接用event.pos获取点击位置,比get_pos()更高效
            x, y = event.pos
            sqx = (x - circle_center_screen[0])**2
            sqy = (y - circle_center_screen[1])**2
            if math.sqrt(sqx + sqy) < 20:
                print ('inside')
    screen.fill((200, 200, 255))
    screen.blit(s, s_rect)
    pygame.draw.circle(s, (0, 0, 0), (20, 20), 20)
    # 可以注释掉屏幕上的测试圆了
    # pygame.draw.circle(screen, (0, 0, 0), (20, 20), 20)
    pygame.display.update()
pygame.quit()

方案二:将鼠标坐标转换为Surface的相对坐标

把屏幕上的鼠标点击位置转换为相对于Surface s 的坐标,这样就可以直接用Surface内的圆心 (20,20) 做检测:

from pygame.locals import *
import pygame, sys, math
pygame.init()
screen = pygame.display.set_mode((640, 480))
s = pygame.Surface((100, 100))
s.fill((255, 0, 0))
s_rect = s.get_rect(center = (300, 300))
running = True
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            x_screen, y_screen = event.pos
            # 计算相对于Surface s的坐标
            x_relative = x_screen - s_rect.left
            y_relative = y_screen - s_rect.top
            # 现在用Surface内的圆心(20,20)检测
            sqx = (x_relative - 20)**2
            sqy = (y_relative - 20)**2
            if math.sqrt(sqx + sqy) < 20:
                print ('inside')
    screen.fill((200, 200, 255))
    screen.blit(s, s_rect)
    pygame.draw.circle(s, (0, 0, 0), (20, 20), 20)
    # pygame.draw.circle(screen, (0, 0, 0), (20, 20), 20)
    pygame.display.update()
pygame.quit()

额外小优化

  • 用 event.pos 直接获取点击位置,比调用 pygame.mouse.get_pos() 更高效,因为MOUSEBUTTONDOWN事件本身就包含点击坐标。
  • 可以提前计算好圆形的绝对圆心或者Surface的位置,避免在循环内重复计算。

内容的提问来源于stack exchange,提问作者Ivan Yosifov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 23:14:08