Python pygame,检测旋转矩形的碰撞

Python pygame,检测旋转矩形的碰撞,python,pygame,Python,Pygame,我画了一个旋转的矩形,我需要检查它是否碰撞。 全班同学: class Laser: def __init__(self, player_x, player_y): self.x = player_x self.y = player_y self.original_image = pygame.Surface((2, 1000)) self.original_image.set_colorkey( (0,0,0) ) self.original_image.

我画了一个旋转的矩形,我需要检查它是否碰撞。 全班同学:

class Laser:
def __init__(self, player_x, player_y):
    self.x = player_x
    self.y = player_y
    self.original_image = pygame.Surface((2, 1000))
    self.original_image.set_colorkey( (0,0,0) )
    self.original_image.fill( (255,0,0) )
    self.copy_image = self.original_image.copy()
    self.copy_image.set_colorkey( (0,0,0) )
    self.rect = self.copy_image.get_rect()
    self.new_image = pygame.Surface((2, 1000))
    self.angle = 0

def continueDrawLaser(self):
    if laser_bool:
        screen.blit(self.new_image, self.rect)

def rotate(self):
    # get rectangle of player and laser, as if the angle would be 0
    player_rect = player1.original_player_image.get_rect(topleft=(player1.x, player1.y))
    laser_rect = self.original_image.get_rect(midbottom=player_rect.midtop)
    self.angle = player1.angle
    pivotPos = [player_rect.centerx - laser_rect.x, player_rect.centery - laser_rect.y]

    # calcaulate the axis aligned bounding box of the rotated image
    w, h = self.original_image.get_size()
    box = [pygame.math.Vector2(p) for p in [(0, 0), (w, 0), (w, -h), (0, -h)]]
    box_rotate = [p.rotate(self.angle) for p in box]
    min_box = (min(box_rotate, key=lambda p: p[0])[0], min(box_rotate, key=lambda p: p[1])[1])
    max_box = (max(box_rotate, key=lambda p: p[0])[0], max(box_rotate, key=lambda p: p[1])[1])

    # calculate the translation of the pivot
    pivot = pygame.math.Vector2(pivotPos[0], -pivotPos[1])
    pivot_rotate = pivot.rotate(self.angle)
    pivot_move = pivot_rotate - pivot

    # calculate the upper left origin of the rotated image
    origin = (laser_rect.x + min_box[0] - pivot_move[0], laser_rect.y - max_box[1] + pivot_move[1])  #x,y

    # get a rotated image
    self.new_image = pygame.transform.rotate(self.original_image, self.angle)

    # get new rectangle
    self.rect = self.new_image.get_rect(topleft=origin)
这是碰撞函数:

#check if rock collides with laser
def collisionRockLaser(self, laser1):
    laser_rect = laser1.rect
    rock_rect = pygame.Rect(self.x, self.y, rock_width, rock_height)
    if laser_rect.colliderect(rock_rect):
        rocks.pop(rocks.index(rock2))
        global score
        score += 1
这就是我得到的:


我认为它足够通过self.rect,因为它随着每次旋转的位置而更新,以检测碰撞,但是似乎我必须使用分离轴定理,你能帮我吗

一个选项是创建与直线和矩形相交的算法

首先创建一个与2条线段相交的算法:

该算法将在对的回答中详细解释

def碰撞线(P0、P1、Q0、Q1):
d=(P1[0]-P0[0])*(Q1[1]-Q0[1])+(P1[1]-P0[1])*(Q0[0]-Q1[0])
如果d==0:
返回错误
t=((Q0[0]-P0[0])*(Q1[1]-Q0[1])+(Q0[1]-P0[1])*(Q0[0]-Q1[0])/d
u=((Q0[0]-P0[0])*(P1[1]-P0[1])+(Q0[1]-P0[1])*(P0[0]-P1[0])/d

返回0谢谢,我真的很感谢附件中的解释。我不知道为什么,但如果我移动非常快的鼠标,碰撞不会被检测到,但它似乎几乎是一个遏制功能,所以它非常好!再次感谢,新年快乐@C-Gian可能激光从未与矩形相交。首先是“之前”,下一帧是“上面”
P     ... point on the 1. line
R     ... normalized direction of the 1. line

Q     ... point on the 2. line
S     ... normalized direction of the 2. line

alpha ... angle between Q-P and R
beta  ... angle between R and S

X     ... intersection point
t     ... distance between P and X
u     ... distance between Q and X

gamma  =  180° - alpha - beta

t  = | Q - P | * sin(gamma) / sin(beta)
u  = | Q - P | * sin(alpha) / sin(beta)

t  =  dot(Q-P, (S.y, -S.x)) / dot(R, (S.y, -S.x))  =  determinant(mat2(Q-P, S)) / determinant(mat2(R, S))
u  =  dot(Q-P, (R.y, -R.x)) / dot(R, (S.y, -S.x))  =  determinant(mat2(Q-P, R)) / determinant(mat2(R, S))

X  =  P + R * t  =  Q + S * u