gpt4 book ai didi

python - pygame,检测旋转矩形的碰撞

转载 作者:行者123 更新时间:2023-12-01 06:38:43 24 4
gpt4 key购买 nike

我绘制了一个旋转的矩形,我需要检查它是否发生碰撞。全类同学:

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

这就是我得到的:

enter image description here

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

最佳答案

一种选择是创建与直线和矩形相交的算法。

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

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

该算法有详细解释,在Problem with calculating line intersections的回答中

def collideLineLine(P0, P1, Q0, Q1):  
d = (P1[0]-P0[0]) * (Q1[1]-Q0[1]) + (P1[1]-P0[1]) * (Q0[0]-Q1[0])
if d == 0:
return False
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
return 0 <= t <= 1 and 0 <= u <= 1

要测试线段是否与矩形相交,您必须测试它是否与矩形的 4 条边中的任何一条相交:

def colideRectLine(rect, p1, p2):

return (collideLineLine(p1, p2, rect.topleft, rect.bottomleft) or
collideLineLine(p1, p2, rect.bottomleft, rect.bottomright) or
collideLineLine(p1, p2, rect.bottomright, rect.topright) or
collideLineLine(p1, p2, rect.topright, rect.topleft))

根据角度沿激光设置一条线:

angle = player1.angle
if angle < 0:
angle += 360

if angle < 90 or (angle > 180 and angle < 270):
laserline = [laser1.rect.topleft, laser1.rect.bottomright]
else:
laserline = [laser1.rect.bottomleft, laser1.rect.topright]

在与 pygame.Rect 相交的线中求值enemy_rect:

collide = colideRectLine(enemy_rect, *laserline)

关于python - pygame,检测旋转矩形的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59553156/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com