Search code examples
pythonpygamespritecollision

Sprite collide with object function?


Is it possible for me to create a function where it displays a message if the Sprite (Rocket) collides with the astroid objects?

class Rocket(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.rect=self.image.get_rect()
        self.image=Rocket.image
        self.firecountdown = 0

    def setup(self):
        self.rect.x=700
        self.rect.y=random.randint(20,380)

    def updateposition(self):
        self.rect.x=self.rect.x-1
        time.sleep(0.005)

        if self.rect.x == 0 :
            self.rect.x = 700 + random.randint(0, 100)
            self.rect.y=random.randint(20,380)


asteroids=[]

asteroidsize=[]

for i in range(25):

        x=random.randrange(700,10000)

        y=random.randrange(0,400)

        asteroids.append([x,y])

        asteroids[i]=Asteroid()

for i in range(25):

        asteroidsize.append(random.randint(6,15))


while True:

        for i in range(len(asteroids)):


        pygame.draw.circle(screen,GREY,asteroids[i],asteroidsize[i])


        asteroids[i][0]-=2



        if asteroids[i][0]<0:

            y=random.randrange(0,400)

            asteroids[i][1]=y

            x=random.randrange(700,720)

            asteroids[i][0]=x

Solution

  • You could write a function on your Rocket class that checks for collisions. Since the asteroids are circles, you'll want to check if the closest point on the circle to the center of your sprite's rect is within the rect's bounds:

    def check_asteroid_collision( self, asteroid, size ) :
        # Create a vector based on the distance between the two points
        distx   = self.rect.centerx - asteroid[0];
        disty   = self.rect.centery - asteroid[1];
        # Get magnitude (sqrt of x^2 + y^2)
        distmag = ((distx * distx) + (disty * disty)) ** 0.5;
    
        # Get the closest point on the circle:
        # Circle center + normalized vector * radius
        clsx    = asteroid[0] + distx / distmag * size;
        clsy    = asteroid[1] + disty / distmag * size;
    
        # Check if it's within our rect
        if self.rect.collidepoint( clsx, clsy ) :
            # We're colliding!! Do whatever
            print( "Oh no!" );
    

    Then in your game loop, you could check collisions by calling this:

    while True:
        for i in range(len(asteroids)):
            ...
            # Collision checking
            myrocket.check_asteroid_collision( asteroids[i], asteroidsize[i] );
    

    Keep in mind this process is somewhat expensive and it will check every asteroid if it's colliding. If there's a large number of asteroids, it'll run slowly.