1

I don't understand why the sprite collision detection is not taking the image rotation into account. I tried different functions but they didn't work out for me.

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

I would like to find a way to detect collision between the sprites in the 2 car groups, or collision between the player sprite and the dummycar_group (each would work out for me) that takes the rotation of the image into account.

What happens now is when I steer the car, the car image rotates but it looks like the collision detection doesn't see that.

Is there a better function i can use that could handle this?

My full source code: dropbox

NickGames
  • 312
  • 1
  • 18

1 Answers1

1

I found this question very interesting and fun to work on and fix! Thanks for posting!

I have found the problem and it is rather unfortunate. Your code runs perfectly from what I have seen. The problem is that pygame uses rectangles for collision detection which are not precise enough.

You are applying the rotation to the image but that just makes it bigger and less accurate. I have highlighted the problem with the addition of rendiering debug lines in the GameLoop function.

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

Add these lines in and you shall see for yourself.

The only solution that I can think of is to add in the functionality to use polygons for collision detection yourself.

The way I would implement this is to:

  • Stop using the rect attribute of all Sprites for collision detection and stop using any methods for collision detection that use the underlying Rects, e.g pygame.sprite.spritecollide().

  • add a pointlist field to all sprites that need it which will store all the points of the polygon

  • Implement your own function that takes in two lists of points and returns if they overlap

I hope that this answer helped you and if you have any further questions please feel free to post a comment below!

Micheal O'Dwyer
  • 1,237
  • 1
  • 16
  • 26
  • Thank you for your response! Your post is very helpful to me, and i'm going to follow your advice. When I make any progress, I will update my post and accept your answer as solution to my problem. – NickGames Jan 14 '18 at 13:32
  • Thanks very much! Good luck implementing this collision detection ;D – Micheal O'Dwyer Jan 14 '18 at 13:33