python - Pygame 碰撞检测不适用于旋转图像

标签 python pygame sprite collision-detection rectangles

我不明白为什么 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/

相关文章:

html - Internet Explorer 6/7 中的 Sprite

c++ - 在一个轴上翻转 D3DX10_SPRITE 不起作用,翻转两个轴都有效

python - Python 可以调用使用 extern "C"和 ctypes 编译的 C++ DLL 库吗?

python - 太空侵略者计划

python - InnoSetup 后出现 cx_freeze fatal error

python - 如何修改我的代码,以便列表中的图像显示在行和图 block 中?

ios - 如何将单个 tileset 图像导入 xCode(Sprite Kit)?

python - Django PositiveIntegerField 接受否定

python - 强制关键字参数

javascript - 无法让 SimpleHTTPRequestHandler 响应 AJAX