在pygame中检测文本框和圆圈之间的碰撞 [英] Detect collision between textbox and circle in pygame

查看:55
本文介绍了在pygame中检测文本框和圆圈之间的碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用python创建一个游戏,可以在屏幕上拖动一个文本框,但是每当它触摸到围绕它的圆的边界时,我都希望循环从头开始,但要使用不同的文本(通过将所有文本字符串存储在列表中,但我还没走那么远).这是我走了多远:

I'm trying to create a game in python where one can drag a textbox around the screen, but whenever it touches the borders of a circle around it, I want the loop to start over, but with a different text (by storing all text-strings in a list, but I'm not that far, yet). This is how far I have come:

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语句,该语句识别我的对象是否发生碰撞(我使用了打印命令,因为我还没有真正想要的命令),但是那赢了不会打印任何东西,我敢肯定我走的路不对,但这是我的最大努力...

Now I understand I will need to detect collision of the borders of my objects, but here I'm pretty lost. I tried to store the variables of my objects in rectangles and then produce another if statement that recognizes whether or not my objects collide (I used a print command because I haven't gotten to the actual command I want, yet), but that won't print anything and I'm sure I'm on the wrong path, but it is my best effort...

为此我定义了:

text_rect = pygame.Rect(x, y, 10, 30)

circle_rect = pygame.Rect(a,b, 300, 300)

,然后在我的循环中:

if circle_rect.colliderect(text_rect): 
     print("COLLIDE")

有人对定义对象和创建所需功能的更好方法有什么建议吗?

Does anybody have any tip on a better way to define the objects and to create the function I want?

(顺便说一句:我不太担心这样的事实,当我拖动文本框时,它会留下文字打印,因为这在我的原始脚本中不会发生,但是如果有人愿意,我会很感激的知道为什么在我当前的示例中会这样做.)

( Btw.: I'm not too concerned about the fact that when I drag my textbox, it leaves a print of the text, since that doesn't happen in my original script, but would be thankful if anyone knows why it does that in my current example.)

推荐答案

一个矩形具有4个角点.如果矩形更小",则圆(圆的直径大于矩形的对角线),如果至少一个点不在圆内且至少在圆上,则矩形与圆的轮廓碰撞一圈是圆.

A rectangle has 4 corner points. If the rectangle is "smaller" then the circle (the diameter of the circle is greater than the diagonal of the rectangle), then the rectangle collides with the contour of a circle, if at least one point is out of the circle and at least one point is in the circle.

定义矩形并设置角点列表.此外,您还必须知道圆的半径:

Define the rectangle and setup a list of the corner points. Further you've to know the radius of the circle:

w, h = 10, 30
rect = pygame.Rect(x, y, 10, 30)

corners = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
radius = 210

计算每个角点到圆心的欧几里德距离(a,b):

Calculate the Euclidean distance of each corner point to the center of the circle (a, b):

import math

dist = [math.sqrt((p[0]-a)**2 + (p[1]-b)**2) for p in corners]

创建到列表,一个带有圆点( p_in ),另一个带有圆点( p_out ):

Create to lists, one with the points in the circle (p_in) and one with the points out of the circle (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]

如果两个列表都包含 任何 元素,则矩形与圆轮廓相交:

If both list contain any element, then the rectangle intersects the circle contour:

if any(p_in) and any(p_out):
    print("COLLIDE")

如果 len(p_in)为4,则矩形完全在圆中.如果 len(p_out)为4,则矩形完全不在圆内.

If len(p_in) is 4, then the rectangle is completely in the circle. If len(p_out) is 4 then the rectangle is completely out of the circle.

if any(p_in) and any(p_out):
    print("COLLIDE")
elif len(p_in) == 4:
    print("IN")
elif len(p_out) == 4:
    print("OUT")


请参见简单示例,该示例基于您的代码段并演示了碰撞测试.矩形已附加到鼠标上:


See the simple example, which is based on your code snippet and demonstrates the collision test. The rectangle is attached to the mouse:

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()

这篇关于在pygame中检测文本框和圆圈之间的碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆