Krishay R.
Krishay R.

Reputation: 2814

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

I have tried to create a function that checks a collision between a static image, and one moving image. In the function, I attempted to create a mask of the moving image (The gun), and a mask of the balloons (static images) that are stored in a list and iterated over. Next, I made a rectangle around both of the images and checked where they overlap. When they overlap, it prints out collision with balloon #. The thing is, it only works at a certain position and doesn't work for all of the balloons. Here is the code:

import pygame as pg
import random as r
import sys

pg.init()

screen = pg.display.set_mode((688 ,387)) # Size of the screen #
screen.fill('#ffffff')

radius = 30
diameter = 2 * radius
num_balloons = 7


def create_balloons():
    global balloon_list
    global colors

    for i in range(num_balloons):
        while True:
            candidate = r.randint(0, 500)
            if all(abs(candidate-x) >= diameter for x in balloon_list):
                break
        balloon_list.append(candidate)

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

def check_collisions(x, y):
    gun_rect = gun.get_rect(center=(x,y))
    gun_mask = pg.mask.from_surface(gun)
    for i in range(num_balloons):
        balloon_rect = colors[i].get_rect()
        balloon_mask = pg.mask.from_surface(colors[i])
        offset = (balloon_rect.x - gun_rect.x), (balloon_rect.y - gun_rect.y)
        if gun_mask.overlap(balloon_mask, offset):
            print(f"collision with balloon {i}")
    



    
# Vars #
x = 0
y = 250
velocity = 5
clock = pg.time.Clock()


caption = pg.display.set_caption("Remember") # Title of the window #

balloon_list = []
b1 = pg.image.load('balloons/1.png').convert_alpha()
b1 = pg.transform.scale(b1, (444,250))
b2 = pg.image.load('balloons/2.png').convert_alpha()
b2 = pg.transform.scale(b2, (444,250))
b3 = pg.image.load('balloons/3.png').convert_alpha()
b3 = pg.transform.scale(b3, (444,250))
b4 = pg.image.load('balloons/4.png').convert_alpha()
b4 = pg.transform.scale(b4, (444,250))
b5 = pg.image.load('balloons/5.png').convert_alpha()
b5 = pg.transform.scale(b5, (444,250))
b6 = pg.image.load('balloons/6.png').convert_alpha()
b6 = pg.transform.scale(b6, (444,250))
b7 = pg.image.load('balloons/7.png').convert_alpha()
b7 = pg.transform.scale(b7, (444,250))
colors = [b1, b2, b3, b4, b5, b6, b7]




gun = pg.image.load('game-gun.png')
gun = pg.transform.scale(gun, (150,150))

create_balloons()



pg.display.flip() # Updating #

running = True # Game loop bool #

while running: # Game loop #
  clock.tick(60)
  for event in pg.event.get():
      if event.type == pg.QUIT:
          pg.quit()
          sys.exit()
      if event.type == pg.KEYDOWN:
          if event.key == pg.K_ESCAPE:
              pg.quit()
              sys.exit()


  keys = pg.key.get_pressed()

  x += keys[pg.K_RIGHT] - keys[pg.K_LEFT] * velocity
  x -= keys[pg.K_LEFT] - keys[pg.K_RIGHT] * velocity
  screen.fill('#ffffff')


  draw_balloons(y)
  check_collisions(x, y)
      
  screen.blit(gun, (x, y))
  pg.display.update()

Since you need images to run the code, you can run the code at this REPL.

Appreciate any help, Thank you.

Upvotes: 1

Views: 86

Answers (1)

Rabbid76
Rabbid76

Reputation: 210968

You must set the location of the balloon_rect. The balloon is drawn at the posiotn (balloon_list[i] - 100, y-90):

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

Therefore the balloon_rect is:

balloon_rect = colors[i].get_rect()

balloon_rect = colors[i].get_rect(topleft = (balloon_list[i]-100, y-90))

Function check_collisions:

def check_collisions(x, y):

    gun_rect = gun.get_rect(center = (x,y))
    gun_mask = pg.mask.from_surface(gun)

    for i in range(num_balloons):

        balloon_rect = colors[i].get_rect(topleft = (balloon_list[i]-100, y-90))
        balloon_mask = pg.mask.from_surface(colors[i])

        offset = (balloon_rect.x - gun_rect.x), (balloon_rect.y - gun_rect.y)
        if gun_mask.overlap(balloon_mask, offset):
            print(f"collision with balloon {i}")

Upvotes: 1

Related Questions