Pygame在两个矩形之间碰撞时找到哪一侧击中

2024-09-30 22:19:44 发布

您现在位置:Python中文网/ 问答频道 /正文

对不起,我的英语和初级的Python知识

我试图找到一种方法,在两个矩形(一个移动的子弹和一个盒子)发生碰撞时,盒子的哪一边撞到了子弹。我正在使用矩形中间,中右,中左,中下找到它。我的问题是子弹一次移动多个像素,当子弹击中盒子但没有足够靠近中心时,它记录了错误的碰撞。你知道吗

示例:

子弹是从屏幕底部出来的,我可以看到它应该是和盒子的底部发生了碰撞,但是它没有碰到盒子矩形中间并触摸右中矩形相反,它注册了错误的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)

你会怎么做?我试着做一个直线矩形,比较角度,使用遮罩,但我找不到解决办法。你知道吗

谢谢你的时间!你知道吗


Tags: orandrectselfboxif错误盒子
1条回答
网友
1楼 · 发布于 2024-09-30 22:19:44

使用方向向量(dxdy)从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"]

您必须确定接近(dxdy)的方向。这可以通过将向量(dxdy)和向量的dot product与th 4方向进行比较来实现,这类似于Check whether a point exists in circle sector or not with Python

一般来说,两个向量的积等于两个向量之间的夹角乘以两个向量的大小(长度):

dot( A, B ) == | A | * | B | * cos( angle_A_B ) 

二维向量A和B的dot product可以通过2次乘法和1次加法来计算:

dotAB = Ax * Bx + Ay * By 

壁橱方向就是方向,它给出了最大值dot product。最大凸轮可以通过^{}找到:

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

        # [...]

相关问题 更多 >