Search code examples
pythonpygamecollision-detection

Barrier shield collision detection for Space Invaders game in Python with pygame


I'm currently making the Space Invaders game in Python with pygame.

I currently have 3 base barriers that are all built with 1 x 1 pixel blocks (that 'extend' the pygame.sprite.Sprite class). For collision detection, I check if a missile has collided with the barrier. For now, everything works, when I fire and hit one of the barriers, the pixel that was hit is eliminated.

Now the thing that bothers me is that in the original Space Invaders, when the ship's missile (or an alien's missile for that matter) hits the barrier, it causes an 'explosion' that affects multiple pixels of the barrier. I would like to implement this in my python/pygame code. How would I go about this?

Here is my collision detection code in my missile class (that 'extends' the pygame.sprite.Sprite):

baseBarrier_hit_list = pygame.sprite.spritecollide(self, all_baseBarrier_group, True)

    for pixel in baseBarrier_hit_list:
        self.kill() # I kill the missile after collision so that the other barrier pixels are unaffected.
        break #so that the other pixels in the column are unaffected.  

I thought of 'artificially' adding 'random' pixels to the baseBarrier_hit_list but I'm unable to add elements to the baseBarrier_hit_list.

Here is a video link of the original space invaders to see what I mean: https://www.youtube.com/watch?v=axlx3o0codc

Here is also a link to a python/pygame version of Space Invaders that shows that only one pixel is affected when collision occurs between missile and base barrier. (Note that this is not MY version of the game). https://www.youtube.com/watch?v=_2yUP3WMDRc

EDIT: (see comment for picture explanation) enter image description here

EDIT: TemporalWolf's suggestion worked. This is the code I added to my function.

shield_hit_list_random = pygame.sprite.spritecollide(self, all_blockShields_group, False, pygame.sprite.collide_rect_ratio(2))

Passing a False to the function prevents the killing of the sprites. Then, I randomly kill the some sprites in the shield_hit_list_random group like this:

for shield in shield_hit_list_random:
    pourcentage =randint(0,3)
    if pourcentage == 2:
        shield.kill()

Solution

  • I would try using the scaled collision rect or the circle equivalent:

    pygame.sprite.collide_rect_ratio() Collision detection between two sprites, using rects scaled to a ratio.

    collide_rect_ratio(ratio) -> collided_callable

    A callable class that checks for collisions between two sprites, using a scaled version of the sprites rects.

    Is created with a ratio, the instance is then intended to be passed as a collided callback function to the *collide functions.

    A ratio is a floating point number - 1.0 is the same size, 2.0 is twice as big, and 0.5 is half the size.

    New in pygame 1.8.1

    which would be given as the 4th parameter to your spritecollide function