我尝试在Pygame中使用预定义的跟踪蒙版来实现光束碰撞检测。我的最终目标是给AI汽车模型一个构想,以查看它行驶的轨迹:
这是我当前的代码,我在其中发射光束以掩蔽并尝试找到重叠的部分:
import math
import sys
import pygame as pg
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
pg.init()
beam_surface = pg.Surface((500, 500), pg.SRCALPHA)
def draw_beam(surface, angle, pos):
# compute beam final point
x_dest = 250 + 500 * math.cos(math.radians(angle))
y_dest = 250 + 500 * math.sin(math.radians(angle))
beam_surface.fill((0, 0, 0, 0))
# draw a single beam to the beam surface based on computed final point
pg.draw.line(beam_surface, BLUE, (250, 250), (x_dest, y_dest))
beam_mask = pg.mask.from_surface(beam_surface)
# find overlap between "global mask" and current beam mask
hit = mask.overlap(beam_mask, (pos[0] - 250, pos[1] - 250))
if hit is not None:
pg.draw.line(surface, BLUE, mouse_pos, hit)
pg.draw.circle(surface, GREEN, hit, 3)
surface = pg.display.set_mode((500, 500))
mask_surface = pg.image.load("../assets/mask.png")
mask = pg.mask.from_surface(mask_surface)
clock = pg.time.Clock()
while True:
for e in pg.event.get():
if e.type == pg.QUIT:
pg.quit()
sys.exit()
mouse_pos = pg.mouse.get_pos()
surface.fill((0, 0, 0))
surface.blit(mask_surface, mask_surface.get_rect())
for angle in range(0, 120, 30):
draw_beam(surface, angle, mouse_pos)
pg.display.update()
clock.tick(30)
让我们描述一下代码片段中发生的情况。我一个接一个地绘制光束到beam_surface
,从中制作蒙版,并发现与由一个矩形和一个圆(gif中的黑色)定义的背景蒙版重叠。如果存在“命中点”(两个蒙版之间的重叠点),则用连接命中点和鼠标位置的线来绘制它。
对于角度<0,90>
,它[[正常]
但是对于<90,360>
范围内的角度,它是[[不起作用
overlap()
文档说明了这一点:从左上角开始,检查第一行的(0,0)至(W-1,0)的位0至W-1,然后继续到下一行((0,1)至(W -1、1))。一旦检查了整个列块,它就会继续到下一个(W到2 * W-1)。
这意味着仅当光束大约从左上角撞击到遮罩时,此方法才有效。您是否有关于如何使其在所有情况下均有效的建议?通常,这是解决此问题的好方法吗?
为了使用蒙版碰撞,您应该通过从另一个对象的坐标减去一个对象的x和y坐标,然后调用第二个对象的蒙版的overlay方法并传递蒙版的蒙版来计算偏移量第一个对象。
也请阅读:overlap()