How do you make a Sprite blitting twice have two separate collision boxes in Pygame?

I don't know if my title was very clear, so I'm going to try to explain this more clearly here. So I have a Sprite in Pygame called spikes. I want there to be more than one spikes so I blit a second one. Problem is, my spike_collision box only works on the first one that I blit, and not the second one. Other than having to make a second collision box, how can I have the second spikes to have its own collision box as well?

Here's the blit code:

        screen.blit(spikes, (spike_x, 500 - player_y + 476))
        screen.blit(spikes, (spike_x + 200, 500 - player_y + 476))

Here's the collision-box code:

spike_collision = spikes.get_rect(topleft=(spike_x, 500 - player_y + 476))

Thanks.

1 answer

  • answered 2020-12-02 00:29 Kingsley

    I'm assuming when you write "sprite", you mean a bitmap-sprite, and not a pygame.sprite.Sprite.

    It's probably best to maintain a sprite as a bitmap and a rectangle, then always draw the sprite at its rectangle, adjusting the rectangle to re-position the sprite, and using it for any collisions.

    This could easily be done with list-pairs:

    spike_image = pygame.image.load('spikes.png').convert_alpha()
    spike_rect  = spike_image.get_rect( )
    spikes_a = [ spike_image, spike_rect( top_left=( 100, 100 ) )
    spikes_b = [ spike_image, spike_rect( top_left=( 200, 200 ) )
    
    # ...
    
    screen.blit( spikes_a[0], spikes_a[1] )
    screen.blit( spikes_b[0], spikes_b[1] )
    # etc.
    
    if ( spikes_a[1].colliderect( player_rect ) ):
        print( "ouch!" )
    

    However, it would behoove you to use a "proper" sprite object. Sure there's a bit of extra set-up, but it's repaid multiple times with ease of use:

    class Spike( pygame.sprite.Sprite ):
        def __init__( self, position=( 0, 0 ) ):
            self.image = pygame.image.load('spikes.png').convert_alpha()
            self.rect  = self.image.get_rect( top_left = position )
    
        def moveTo( self, position ):
            self.rect  = self.image.get_rect( top_left = position )
    
        def moveBy( self, dx, dy ):
            self.rect.move_ip( dx, dy )
    
    
    spike_a = Spike( ( 100, 100 ) )
    spike_b = Spike( ( 200, 200 ) )
    
    spike_a.draw( window )  # get this for free
    

    There's a whole lot of useful group & collision functionality that comes along with using Sprite objects, it's well worth a read: https://www.pygame.org/docs/ref/sprite.html