Help with collision detection in game

I’ve been trying to detect a mouse click within a bouncing ball using the following codes. However, I’m getting a “False” when I click on the ball instead of a “True” when I print the result of the collidepoint code. Anyone knows what I’m doing wrongly?

#From the Main file
# Check for and handle events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONUP:
            oBall.handleEvent(event)

#From the Class file
self.image = pygame.image.load('images/ball.png')
self.ballRect = self.image.get_rect()

def handleEvent(self, eventObj):

        if eventObj.type == pygame.MOUSEBUTTONUP:
            if self.ballRect.collidepoint(eventObj.pos):
               print('User has clicked on ball')

I don’t know anything about pygame, but is the mouse-button-up event really delegated from the parent to the oBall? You could try to debug by tracing through this in a debugger (usually a pain with event-driven applications) or simply by adding some temporary print statements:

  • just before oBall.handleEvent (I’d also add the event.pos)
  • just before if self.ballRect.collidePoint or perhaps even as first line in handleEvent (it should hopefully not lead to a waterfall of log messages since I assume only some kinds of event or passed to that event handler); alternatively: simply add 'eventObj.pos` to the print statement you already have

Well, did you check what the self.ballRect and eventObj.pos values are? Are they what you expect? According to the values that you see (not according to how you actually operate the program), do you expect the collidepoint check to pass? Why?

(Hint: what part of the code causes the ball to move? Where is the ball? Why should the self.ballRect have anything to do with that position?)

(Hint: where does the code say self.ballRect = self.image.get_rect()? Therefore, when will that change happen? If the ball moves, will it cause that code to run again? Therefore, will self.ballRect change?)

I’ve added a few print statements to check the status of the various codes(see below). I’m getting the following output:

pygame-ce 2.3.2 (SDL 2.26.5, Python 3.10.13)
Calling eventHandler
Checking
False

So control is reaching the relevant part of my codes, but the detection of the mouseclick within the ball, when I click on it, is still coming out False. Even if I comment out the movement of the ball, and it is stationary, I’m still getting a False when I click on the ball. I confirmed this via the “print(self.ballRect.collidepoint(eventObj.pos))”, which is reporting “False”. But it should be True since I’ve clicked on the ball. This is the nub of my problem. Thanks for helping to check.

def handleEvent(self, eventObj):

        if eventObj.type == pygame.MOUSEBUTTONUP:
            print('Checking')
            print(self.ballRect.collidepoint(eventObj.pos))
            self.ballRect = self.image.get_rect()
            if self.ballRect.collidepoint(eventObj.pos):
                print('User has clicked on ball')

Start by printing the actual values of eventObj.pos and self.ballRect.

OK. I’ve followed your advice to print the values, and realized I was trying to use the image co-ordinates in my class file instead of the instantiated object itself in my program (or main) file. Now, I just need to find out how to get the position (or rect) of my instantiated object. I tried using get_rect(), but was told by interpreter that an object has no get_rect() attribute.

Update:
I found the position of my moving object using pygame.Rect(x co-ord,y co-ord,width, height). Thks for your pointers.

2 Likes