Collisions using masks between two images only working at a certain point

Viewed 144

I am trying to check a collision between one static, and one moving image. The static image is a balloon and the moving image is a gun. I've tried to create a function that gets the rect of the gun (using get_rect), checks if one of the (7) balloons (stored in a list) has the same x coordinate (x coordinate is randomly generated), and prints out which balloon it collided with. But it doesn't always seem to work, and only works in a certain position. Also, it prints out something like collision with [<Surface(444x250x32 SW)> when it should print the name (variable name) of which one of the balloons it hit.

Edit: Using Rabbid's suggestions, I've made a mask around both the balloon and the gun and tried checking those for the collision. They still don't work, but I feel like I am getting closer. I also made a repl, so you can run the code yourself. Here it is: Repl

enter image description here (When the gun is in the same position as the balloon, it should print out which balloon it hit.)

How can I check the collisions between these images properly, and print out which balloon was hit?

1 Answers

pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the top left of the rectangle can be specified with the keyword argument topleft. e.g.:

gun_rect = gun.get_rect(topleft = (x, y))

Read How do I detect collision in pygame? and use pygame.Rect.collidepoint to detect the collision of the gun tip (gun_rect.topleft) with the enclosing rectangle of a balloon (ballon_rect):

def check_collisions(x, y):
    for i in range(num_balloons):
        gun_rect = gun.get_rect(topleft = (x,y))
        ballon_rect = colors[i].get_rect(topleft = (balloon_list[i] - 100, y-90))
        if ballon_rect.collidepoint(gun_rect.topleft):
            print(f'collision with {colors[i]}')
while running: # Game loop #
    # [...]

    check_collisions(x, y)

    # [...]

Note, that the position of the balloon is (balloon_list[i] - 100, y-90), since you are drawing it at that position:

def draw_balloons(y):
   for i in range(num_balloons):
       screen.blit(colors[i], (balloon_list[i] - 100, y-90))   
Related