对不起,我对python的英语学习和初学者了解
我正试图找到一种方法,在两个矩形(移动的子弹和盒子)之间发生碰撞时,获得盒子的哪一侧碰到子弹。我目前正在使用子弹的rect.midtop,中右,中左,中下找到它。我的问题是,子弹一次移动多个像素,当子弹击中盒子但距离中心不够远时,它记录了错误的碰撞。
示例:
项目符号来自屏幕的底部,我可以看到它应该是与盒子底部的碰撞,但是它没有碰到rect.midtop,而是碰到了rect.midright,它注册了错误的Collison事件。
这是我的碰撞代码:
if self.bullet.rect.collidelist(self.listbox):
self.bullet.pretx1 = 1
self.bullet.pretx2 = 1
self.bullet.prety = 1
self.bullet.pret = 1
for box in self.listbox:
if box.rect.collidepoint(self.bullet.rect.midtop) or box.rect.collidepoint(self.bullet.rect.midbottom) and self.a == 1:
self.a = 0
print("vertical")
print(self.bullet.angle)
self.bullet.angle = abs(360 - self.bullet.angle)
print(self.bullet.angle)
self.listbox.remove(box)
elif box.rect.collidepoint(self.bullet.rect.midleft) or box.rect.collidepoint(self.bullet.rect.midright) and self.a == 1:
self.a = 0
print("horizontal")
print(self.bullet.angle)
self.bullet.angle = 180 - self.bullet.angle
print(self.bullet.angle)
if self.bullet.angle < 0:
self.bullet.angle += 360
print(self.bullet.angle)
self.listbox.remove(box)
你会怎么做?我试图使用遮罩来对直线进行比较,比较角度,但无法找到可行的解决方案。
感谢您的时间!
答案 0 :(得分:2)
使用从dx
中心到dy
中心的方向向量(box
,bullet
)来确定该框是否适合左侧,右,上或下:
dx = self.bullet.rect.centerx - box.rect.centerx
dy = self.bullet.rect.centery - box.rect.centery
必须测试的4个方向是:
dir = [(-1, 0), (1, 0), (0, -1), (0, 1)]
dirName = ["left", "right", "top", "bottom"]
您必须确定靠近(dx
,dy
)的方向。可以通过比较向量dot product(dx
,dy
)和向量与第4个方向的向量来完成,这类似于Check whether a point exists in circle sector or not with Python
通常,两个向量的 dot 乘积等于两个向量之间的角度的 cosine 乘以两个向量的大小(长度):
dot( A, B ) == | A | * | B | * cos( angle_A_B )
二维向量A和B的dot product可以通过2次乘法和1次加法来计算:
dotAB = Ax * Bx + Ay * By
壁橱方向为,给出最大dot product。通过max
找到最大的凸轮:
max_dir = max([i for i in range(len(dir))], key = lambda i: dx*dir[i][0] + dy*dir[i][1])
例如
dir = [(-1, 0), (1, 0), (0, -1), (0, 1)]
dirName = ["left", "right", "top", "bottom"]
for box in self.listbox:
if box.rect.colliderect(self.bullet.rect):
dx = self.bullet.rect.centerx - box.rect.centerx
dy = self.bullet.rect.centery - box.rect.centery
max_dir = max([i for i in range(len(dir))], key = lambda i: dx*dir[i][0] + dy*dir[i][1])
print("hit", dirName[max_dir])
# [...]