我正在尝试用 python 创建一个游戏,可以在屏幕上拖动一个文本框,但每当它触及周围圆圈的边界时,我希望循环重新开始,但使用不同的文本(通过将所有文本字符串存储在列表中,但我还没有那么远)。这就是我已经走了多远:
import pygame
import ptext
pygame.init()
gameDisplay = pygame.display.set_mode((500, 500))
gameDisplay.fill((255,255,255))
x = 190
y = 230
a = 250
b = 250
text = "ExampleText 1."
def textbox(x,y):
ptext.draw(text, (x,y), color = (0,0,0))
def circle(a,b):
pygame.draw.circle(gameDisplay, (0,0,0), (250, 250), 210, 5)
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]:
x += event.rel[0]
y += event.rel[1]
textbox(x,y)
circle(a,b)
pygame.display.flip()
pygame.quit()
quit()
现在我知道我需要检测对象边界的碰撞,但在这里我很迷失。我尝试将对象的变量存储在矩形中,然后生成另一个 if 语句来识别我的对象是否发生碰撞(我使用了打印命令,因为我还没有得到我想要的实际命令),但这赢了不打印任何内容,我确信我走错了路,但这是我最大的努力......
为此我定义了:
text_rect = pygame.Rect(x, y, 10, 30)
circle_rect = pygame.Rect(a,b, 300, 300)
然后在我的循环中:
if circle_rect.colliderect(text_rect):
print("COLLIDE")
有人对定义对象和创建我想要的函数有更好的方法吗?
(编辑:顺便说一句:我不太关心当我拖动文本框时,它会留下文本的打印,因为这在我的原始脚本中不会发生,但如果有人知道为什么在我当前的示例中会这样做。)
最佳答案
矩形有 4 个角点。如果矩形比圆“小”(圆的直径大于矩形的对角线),则矩形与圆的轮廓碰撞,如果至少有一个点在圆之外并且至少一点在圆内。
定义矩形并设置角点列表。此外,您还必须知道圆的半径:
w, h = 10, 30
rect = pygame.Rect(x, y, 10, 30)
corners = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
radius = 210
计算Euclidean distance每个角点指向圆心 (a, b)
:
import math
dist = [math.sqrt((p[0]-a)**2 + (p[1]-b)**2) for p in corners]
创建列表,一个包含圆内的点 (p_in
),另一个包含圆外的点 (p_out
):
p_out = [i for i, d in enumerate(dist) if d > radius]
p_in = [i for i, d in enumerate(dist) if d < radius]
如果两个列表都包含 any
元素,则矩形与圆形轮廓相交:
if any(p_in) and any(p_out):
print("COLLIDE")
如果len(p_in)
为4,则矩形完全位于圆内。如果 len(p_out) 为 4,则矩形完全脱离圆。
if any(p_in) and any(p_out):
print("COLLIDE")
elif len(p_in) == 4:
print("IN")
elif len(p_out) == 4:
print("OUT")
查看简单的示例,它基于您的代码片段并演示了碰撞测试。矩形附加到鼠标上:
import pygame
import math
pygame.init()
gameDisplay = pygame.display.set_mode((500, 500))
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
x, y = pygame.mouse.get_pos()
w, h = 10, 30
rect = pygame.Rect(x, y, 10, 30)
a, b = 250, 250
radius = 210
corners = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
dist = [math.sqrt((p[0]-a)**2 + (p[1]-b)**2) for p in corners]
p_out = [i for i, d in enumerate(dist) if d > radius]
p_in = [i for i, d in enumerate(dist) if d < radius]
if any(p_in) and any(p_out):
print("COLLIDE")
elif len(p_in) == 4:
print("IN")
elif len(p_out) == 4:
print("OUT")
gameDisplay.fill((255,255,255))
pygame.draw.rect(gameDisplay, (255, 0, 0), rect)
pygame.draw.circle(gameDisplay, (0,0,0), (a, b), radius, 5)
pygame.display.flip()
pygame.quit()
quit()
关于python - 检测pygame中文本框和圆圈之间的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58305721/