Search code examples
pythonimagepygamecollision-detection

How can I detect if my two images are touching in Pygame?


I'm making a game where ASL handsigns fall down and you need to catch them in a bucket. When the sign touches the bucket, I want it to print that they are touching. If they aren't, I want it to print that they are not touching. How do I detect if the images are touching? I have some rect collision code already in, but it just constantly prints out that they are touching one of the signs even when they aren't. Thanks in advance for any help you can give me! P.S. Sorry for putting in all my code but I'm not sure what is needed to see to help solve my problem.

I looked at many questions and answers involving image collision but I can't seem to make it work in my code. I '''highlighted''' the code that I think is causing the problem.

import random
import pygame
pygame.init()
pygame.mixer.init()
#define functions
def newPlacement():
    screen.blit(choiceASL, (x,y))
    screen.blit(choiceASL2, (x2,y2))
    screen.blit(choiceASL3, (x3,y3))
def bucketStuff():
    screen.blit(bucketPic, (bucketX, bucketY))
'''
def ifCollided():
    if bucketRect.colliderect(choiceASLRect):
        print("You collided with choice1!")
    elif bucketRect.colliderect(choiceASL2Rect):
        print("You collided with choice2!")
    elif bucketRect.colliderect(choiceASL3Rect):
        print("You collided with choice3!")
    else:
        print("Not touching.")
'''

#define stuff below: var, funct, def, etc.
aslABCSList = ("AslA.png", "AslB.png", "AslC.png", "AslD.png")
randHandsign = random.choice(aslABCSList)
randHandsign2 = random.choice(aslABCSList)
randHandsign3 = random.choice(aslABCSList)
choiceASL = pygame.image.load(randHandsign)
choiceASLRect = choiceASL.get_rect()
choiceASL2 = pygame.image.load(randHandsign2)
choiceASL2Rect = choiceASL2.get_rect()
choiceASL3 = pygame.image.load(randHandsign3)
choiceASL3Rect = choiceASL3.get_rect()
bucketPic = pygame.image.load("bucketPic.png")
bucketRect = bucketPic.get_rect()

screen = pygame.display.set_mode((700, 600))
Black = [0, 0, 0]
White = [255, 255, 255]
y = 0
y2 = 0
y3 = 0
x = int(random.randrange(1,650,25))
x2 = int(random.randrange(1,650,25))
x3 = int(random.randrange(1,650,50))
bucketX = 300
bucketY = 540

#to make the main work
done = False
#allows fps rate
clock = pygame.time.Clock()

#basically main, put anything that you want to run consistently until the user exits below.
while not done:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        done = True
        #vvv Put all main code here! vvv
        screen.fill(White)
        bucketStuff()
        newPlacement()
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_LEFT]: bucketX -= 3
        if pressed[pygame.K_RIGHT]: bucketX += 3
        ifCollided()

        y+=1
        y2+=2
        y3+=3



        #below is basically a refresh, so that everything is updated. Put code before this!
        pygame.display.flip()
        #60 fps
        clock.tick(50)

Solution

  • The .get_rect() of a pygame.Surface object returns a rectangle with the size of the surface, but at location (0, 0).
    You've to set the location of the image (pygame.Rect):

    e.g.:

    choiceASL = pygame.image.load(randHandsign)
    choiceASLRect = choiceASL.get_rect()
    
    # [...]
    
    bucketPic = pygame.image.load("bucketPic.png")
    bucketRect = bucketPic.get_rect()
    
    # [...]
    
    while not done:
    
        # [...]
    
        if pressed[pygame.K_LEFT]: bucketX -= 3
        if pressed[pygame.K_RIGHT]: bucketX += 3
    
        bucketRect.topleft = (bucketX, bucketY)
        choiceASLRect.topleft = (x, y)
        # [...]
    
        ifCollided()
    

    Once the location of the rectangles is proper set, then the collision test will work as expected.