Search code examples
pythonpygame

Detecting if two sprites overlap using PyGame


I am trying to make my own game and i need to know when two sprites overlap and if they overlap then the game will load in a new picture using win.blit I have tried looking at other peoples posts but they didnt help me at all. I am new, please give an in-depth explanation

EDIT: Please make it as short as possible

EDIT 2 (about 2 years later): Sorry for making such a shit question lol


Solution

  • As short as possible.

    if ( sprite1.rect.colliderect( sprite2.rect ) ):
        # TODO handle collision
    

    But for a more useful example...

    Create a global sprite group. The sprite group allows the code to do a simple check for collisions on the whole group at once. Maybe two groups could be useful, e.g.: aliens and bullets, biscuits and dips.

    SPRITES = pygame.sprite.Group()
    

    Define a sprite. The sprite's update() function is called each frame to do everything the sprite needs to do inter-frame. This might be move, change the bitmap (for animation), or check for collisions, etc. This sprite has a name so we can print out who collides with whom.

    class RockSprite(pygame.sprite.Sprite):
        def __init__(self, name, image, position):
            pygame.sprite.Sprite.__init__(self)
            self.name         = name
            self.image        = image
            self.rect         = self.image.get_rect()
            self.rect.center  = position
    
        def update(self):
            # Move the sprite
            # ... TODO
            # Have we collided with any sprite?
            hit_by = pygame.sprite.spritecollide( self, SPRITES, False )
            hit_by.remove( self ) # other than ourselves
            for other_sprite in hit_by:
                print( "Sprite [%s] collided with [%s]" % ( self.name, other_sprite.name ) )
    

    Create a bunch of sprites. This shows how to create an instance of a RockSprite, and add it to the SPRITE group.

    # Make some sprites, including two that overlap (but it depends on the .png size)
    sprite_image = pygame.image.load("rock.png").convert_alpha()
    rock_01 = RockSprite( "rock01", sprite_image, (10, 10) )
    rock_02 = RockSprite( "rock02", sprite_image, (15, 15) )
    rock_03 = RockSprite( "rock03", sprite_image, (50, 50) )
    # Add them to the global SPRITE group
    SPRITES.add(rock_01)        
    SPRITES.add(rock_02)
    SPRITES.add(rock_03)
    

    Be sure to call the sprite group update() function in the main loop:

    while not done:
    
        # Move the sprites (and checks for collisions) - calls update() on each member
        SPRITES.update()
    
        # paint he screen
        # handle user input  
        ...
    

    Which gives the full demonstration code:

    import pygame
    WINDOW_WIDTH=400
    WINDOW_HEIGHT=400
    
    pygame.init()
    WINDOW  = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    SPRITES = pygame.sprite.Group()
    
    class RockSprite(pygame.sprite.Sprite):
        def __init__(self, name, image, position):
            pygame.sprite.Sprite.__init__(self)
            self.name         = name
            self.image        = image
            self.rect         = self.image.get_rect()
            self.rect.center  = position
    
        def update(self):
            # Move the sprite
            # ... TODO
            # Have we collided with any sprite?
            hit_by = pygame.sprite.spritecollide( self, SPRITES, False )
            hit_by.remove( self ) # other than ourselves
            for other_sprite in hit_by:
                print( "Sprite [%s] collided with [%s]" % ( self.name, other_sprite.name ) )
    
    
    # Make some sprites, including two that overlap
    sprite_image = pygame.image.load("rock.png").convert_alpha()
    rock_01 = RockSprite( "rock01", sprite_image, (10, 10) )
    rock_02 = RockSprite( "rock02", sprite_image, (15, 15) )
    rock_03 = RockSprite( "rock03", sprite_image, (90, 90) )
    # Add them to the global SPRITE group
    SPRITES.add(rock_01)
    SPRITES.add(rock_02)
    SPRITES.add(rock_03)
    
    clock = pygame.time.Clock()
    done = False
    while not done:
    
        # Move the sprites (and checks for collisions)
        SPRITES.update()
    
        # Paint the screen
        WINDOW.fill( ( 0,0,0 ) )
        SPRITES.draw( WINDOW )
        pygame.display.update()
        pygame.display.flip()
    
        # Check for user-events
        for event in pygame.event.get():
            if (event.type == pygame.QUIT):
                done = True
    
        clock.tick_busy_loop(60)