首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在电子游戏中,如何检查直线和直线之间的碰撞?

在电子游戏中,如何检查直线和直线之间的碰撞?
EN

Stack Overflow用户
提问于 2019-05-12 15:08:48
回答 3查看 3.1K关注 0票数 4

我目前正在用蟒蛇创建一个游戏,我的AI目前正在通过墙壁“看到”我的角色并向它射击,但是AI不应该拍摄。因此,我的问题是:如何防止这种情况发生?我想过一次线碰撞,线从我的人工智能到我的角色,如果这条线撞到一堵墙,那么这个人工智能就不会射击。任何帮助都将不胜感激,非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-12 23:49:10

这是个很棒的问题!

你的长方形可以被认为是四行:

代码语言:javascript
运行
复制
(x, y)        → (x+width, y)        # top
(x+width, y)  → (x+width, y+height) # right
(x, y+height) → (x+width, y+height) # bottom
(x, y)        → (x, y+height)       # left 

以您的相交线为例,可以使用二线相交公式来确定这些线中是否有任何一条是相交的(但是要小心平行线!)

然而,公式(在链接的维基百科文章中指定)决定了这些线在2D平面上是否相交,因此需要进一步改进。显然,代码可以迅速丢弃在窗口维度之外发生的任何交叉点。

一旦确定了“无限平面”碰撞点(这是一个合理的快速确定),那么就可以确定一个更细粒度的交叉点。使用Bresenham算法,枚举相交线中的所有点,并将它们与基于正方形两边的1像素矩形进行比较。这将告诉您矩形的哪一侧相交。

如果只需要知道矩形是否被击中,只需使用pygame.Rect.collidepoint()检查整个矩形中的每一个点。

当然,一旦生成了所有这些点,就很容易避免2D行冲突,但是对于长行,代码必须进行大量检查。所以首先测试2D交叉口会加快速度。

票数 3
EN

Stack Overflow用户

发布于 2022-06-05 22:14:55

基本上,是不存在一种方法或任何游戏功能来检测与线的碰撞,这就是为什么我必须想出我将要展示的解决方案。

使用下面的链接,在区段公式/在每个线段上给定两个点时,您可以找到一个公式来知道两条线是否相交,如果它们相交,它们到底在哪里。

其基本思想是检查光源中的每一条光线是否与矩形的四个边中的任意一个相交,如果是的话,光盘应该在矩形的同一侧结束。

代码语言:javascript
运行
复制
import pygame, math

pygame.init()

screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Rays')
pygame.mouse.set_visible(False)

DENSITY = 500
RADIUS = 1000

run = True
while run:
    screen.fill('black')

    rect = pygame.Rect(50, 200, 100, 50)
    pygame.draw.rect(screen, 'red', rect)

    for i in range(DENSITY):
        mouse_pos = pygame.mouse.get_pos()
        pos_fin = (RADIUS * math.cos(2*math.pi / DENSITY * i) + mouse_pos[0], RADIUS * math.sin(2*math.pi / DENSITY * i) + mouse_pos[1])
        if rect.collidepoint(mouse_pos) == False:
            for extrem_1, extrem_2 in [(rect.bottomright, rect.topright), (rect.topright, rect.topleft), (rect.topleft, rect.bottomleft), (rect.bottomleft, rect.bottomright)]:
                deno = (mouse_pos[0] - pos_fin[0]) * (extrem_1[1] - extrem_2[1]) - (mouse_pos[1] - pos_fin[1]) * (extrem_1[0] - extrem_2[0])
                if deno != 0:
                    param_1 = ((extrem_2[0] - mouse_pos[0]) * (mouse_pos[1] - pos_fin[1]) - (extrem_2[1] - mouse_pos[1]) * (mouse_pos[0] - pos_fin[0]))/deno
                    param_2 = ((extrem_2[0] - mouse_pos[0]) * (extrem_2[1] - extrem_1[1]) - (extrem_2[1] - mouse_pos[1]) * (extrem_2[0] - extrem_1[0]))/deno
                    if 0 <= param_1 <= 1 and 0 <= param_2 <= 1:
                        p_x = mouse_pos[0] + param_2 * (pos_fin[0] - mouse_pos[0])
                        p_y = mouse_pos[1] + param_2 * (pos_fin[1] - mouse_pos[1])
                        pos_fin = (p_x, p_y)
            pygame.draw.aaline(screen, 'white', mouse_pos, pos_fin)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    
    pygame.display.update()
pygame.quit()

它可能不是最好的,也是最优化的代码,但最终你应该得到一些有用的东西。

票数 0
EN

Stack Overflow用户

发布于 2022-10-18 20:53:23

检测矩形和直线之间碰撞的最简单方法是使用pygame.Rect.clipline

返回裁剪成完全位于矩形内的线条的坐标。如果行不与矩形重叠,则返回一个空元组。

例如:

代码语言:javascript
运行
复制
rect = pygme.Rect(x, y, width, height)
if rect.clipline((x1, y1), (x2, y2)):
    print("hit")

极小例子

代码语言:javascript
运行
复制
import pygame

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

rect = pygame.Rect(180, 180, 40, 40)
speed = 5
lines = [((20, 300), (150, 20)), ((250, 20), (380, 250)), ((50, 350), (350, 300))]

run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 

    keys = pygame.key.get_pressed()
    rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
    rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
    rect.centerx %= window.get_width()
    rect.centery %= window.get_height()

    color = "red" if any(rect.clipline(*line) for line in lines) else "green"

    window.fill(0)
    pygame.draw.rect(window, color, rect)
    for line in lines:
        pygame.draw.line(window, "white", *line)
    pygame.display.flip()

pygame.quit()
exit()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56100547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档