我不明白为什么 Sprite 碰撞检测没有考虑图像旋转。 我尝试了不同的功能,但它们不适合我。
CarSprites.py:
import pygame, math, random
class CarSprite(pygame.sprite.Sprite):
MIN_FORWARD_SPEED = 5
ACCELERATION = 2
TURN_SPEED = 5
IS_DUMMY = False
def __init__(self, image, position, direction):
pygame.sprite.Sprite.__init__(self)
self.src_image = pygame.transform.scale(pygame.image.load(image), (51, 113))
self.position = position
self.rect = self.src_image.get_rect()
self.rect.center = self.position
self.speed = 0
self.direction = direction
self.k_left = self.k_right = self.k_down = self.k_up = 0
def update(self, deltat):
# SIMULATION
#speed
self.speed += (self.k_up + self.k_down)
if self.speed < self.MIN_FORWARD_SPEED:
self.speed = self.MIN_FORWARD_SPEED
self.speed += (self.k_up + self.k_down)
if self.speed > self.MIN_FORWARD_SPEED * 2:
self.speed = self.MIN_FORWARD_SPEED * 2
#direction
self.direction += (self.k_right + self.k_left)
x, y = self.position
rad = self.direction * math.pi / 180
x += -self.speed*math.sin(rad)
y += -self.speed*math.cos(rad)
self.position = (x, y)
self.image = pygame.transform.rotate(self.src_image, self.direction)
self.rect = self.image.get_rect()
self.rect.center = self.position
#Emulate friction with road and wind
if self.speed > self.MIN_FORWARD_SPEED :
self.speed += -0.1
class DummyCarSprite(pygame.sprite.Sprite):
#MIN_FORWARD_SPEED = 5
#MIN_REVERSE_SPEED = 10.1
#MAX_FORWARD_SPEED_ABOVE_MIN = 5
#ACCELERATION = 2
#TURN_SPEED = 5
def __init__(self, image, position, direction):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.transform.scale(pygame.image.load(image), (51, 113))
self.position = position
self.rect = self.image.get_rect()
self.rect.center = self.position
self.speed = 0
self.direction = direction
self.k_left = self.k_right = self.k_down = self.k_up = 0
if random.randint(0,1) == 1 :
self.direction = self.direction + 180
game.py
def GetDummyCars() :
allDummyCars = [
#Row1
#DummyCarSprite(getCarImage(), (211.9915431212928, 209.36603413022453), 180),
#DummyCarSprite(getCarImage(), (268.9915431212928, 209.36603413022453), 180),
DummyCarSprite(getCarImage(), (325.9915431212928, 209.36603413022453), 180),
DummyCarSprite(getCarImage(), (382.9915431212928, 209.36603413022453), 180)
#etc. etc.
]
dummyCars = []
for dummyCar in allDummyCars :
if random.randint(0,1) == 1 :
dummyCars.append(dummyCar)
return pygame.sprite.RenderPlain(*dummyCars)
playerCar = CarSprite(playerCarImagePath, (1550, 100), 90)
playerCar_group = pygame.sprite.RenderPlain(playerCar)
dummyCar_group = GetDummyCars()
#collisions with dummy cars
dummyCarCollisions = pygame.sprite.groupcollide(playerCar_group, dummyCar_group)
if dummyCarCollisions != {}:
lose_condition = True
playerCar.src_image = pygame.image.load('images/collision.png')
seconds = 0
playerCar.speed = 0
playerCar.MIN_FORWARD_SPEED = 0
playerCar.MAX_FORWARD_SPEED_ABOVE_MIN = 0
playerCar.k_right = 0
playerCar.k_left = 0
我想找到一种方法来检测 2 个汽车组中的 Sprite 之间的碰撞,或者玩家 Sprite 和 dummycar_group 之间的碰撞(每个都适合我),并将图像的旋转考虑在内。
现在发生的情况是,当我驾驶汽车时,汽车图像旋转,但碰撞检测似乎没有看到这一点。
我可以使用更好的函数来处理这个问题吗?
我的完整源代码:dropbox
最佳答案
我发现这个问题非常有趣,并且解决和解决起来很有趣!感谢您发帖!
我发现了这个问题,而且很不幸。从我所看到的来看,你的代码运行得非常完美。问题是 pygame 使用矩形进行碰撞检测,不够精确。
您正在对图像应用旋转,但这只会使其变得更大且不太准确。我已经强调了在 GameLoop
函数中添加渲染调试行的问题。
# draw some debug lines
pygame.draw.rect(screen, (255, 0, 0), playerCar.rect, 1)
for dummyCar in dummyCar_group.sprites():
pygame.draw.rect(screen, (0, 0, 255), dummyCar.rect, 1)
添加这些行,您将亲眼看到。
我能想到的唯一解决方案是添加自己使用多边形进行碰撞检测的功能。
我实现这个的方法是:
停止使用所有 Sprite 的
rect
属性进行碰撞检测,并停止使用任何使用底层 Rect 的碰撞检测方法,例如pygame.sprite.spritecollide()
.向所有需要它的 Sprite 添加一个
pointlist
字段,该字段将存储多边形的所有点实现您自己的函数,该函数接受两个点列表并在它们重叠时返回
希望这个回答对您有所帮助,如果您还有其他问题,请随时在下面发表评论!
关于python - Pygame 碰撞检测不适用于旋转图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48242383/