我目前正在用蟒蛇创建一个游戏,我的AI目前正在通过墙壁“看到”我的角色并向它射击,但是AI不应该拍摄。因此,我的问题是:如何防止这种情况发生?我想过一次线碰撞,线从我的人工智能到我的角色,如果这条线撞到一堵墙,那么这个人工智能就不会射击。任何帮助都将不胜感激,非常感谢!
发布于 2019-05-12 23:49:10
这是个很棒的问题!
你的长方形可以被认为是四行:
(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交叉口会加快速度。
发布于 2022-06-05 22:14:55
基本上,是不存在一种方法或任何游戏功能来检测与线的碰撞,这就是为什么我必须想出我将要展示的解决方案。
使用下面的链接,在区段公式/在每个线段上给定两个点时,您可以找到一个公式来知道两条线是否相交,如果它们相交,它们到底在哪里。
其基本思想是检查光源中的每一条光线是否与矩形的四个边中的任意一个相交,如果是的话,光盘应该在矩形的同一侧结束。
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()
它可能不是最好的,也是最优化的代码,但最终你应该得到一些有用的东西。
发布于 2022-10-18 20:53:23
检测矩形和直线之间碰撞的最简单方法是使用pygame.Rect.clipline
返回裁剪成完全位于矩形内的线条的坐标。如果行不与矩形重叠,则返回一个空元组。
例如:
rect = pygme.Rect(x, y, width, height)
if rect.clipline((x1, y1), (x2, y2)):
print("hit")
极小例子
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()
https://stackoverflow.com/questions/56100547
复制相似问题