pygame-查找两个矩形之间的碰撞过程中撞到哪一侧

时间:2019-04-16 14:52:52

标签: python pygame

对不起,我对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)

你会怎么做?我试图使用遮罩来对直线进行比较,比较角度,但无法找到可行的解决方案。

感谢您的时间!

1 个答案:

答案 0 :(得分:2)

使用从dx中心到dy中心的方向向量(boxbullet)来确定该框是否适合左侧,右,上或下:

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"]

您必须确定靠近(dxdy)的方向。可以通过比较向量dot productdxdy)和向量与第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]) 

        # [...]