Search code examples
pythonpygamepositionmouseevent

pygame detecting if drawn circle sprite is clicked failing


I am working on a small game where if you click a circle it makes a pop sound and goes back to the bottom my problem is when I switched to using a class and sprite to allow multiple circles it no longer will detect if one is clicked what am I doing wrong?

class Bubble(pygame.sprite.Sprite):
    def __init__(self):

        self.radius = random.randint(50,100)
        self.image = pygame.Surface([self.radius/2,self.radius/2])
        self.image.fill(blue)
        self.image = pygame.image.load(bPath+"Images\\Bubble.png")
        self.rect = self.image.get_rect()
        self.bx = random.randint(70, 1466)
        self.x = self.bx
        self.y = 930
        self.way = 0
        self.rect.x = self.x
        self.rect.y = self.y

    def move(self):
        pygame.draw.circle(tv,blue,(self.x,self.y),self.radius)
        
        self.y -= 2

        if self.x == self.bx+20:
            self.way = 1
        elif self.x == self.bx-20:
            self.way = 0
        else:
            pass

        if self.way == 0:
            self.x += 1
        else:
            self.x -= 1

        if self.y <= 0:
            self.bx = random.randint(70, 1466)
            self.x = self.bx
            self.y = 930
            self.radius=random.randint(50,100)
        else:
            pass

bubbleList = []

nBubble = 0
while True:
    tv.fill(white)

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            for b in bubbleList:
                if b.rect.collidepoint(pygame.mouse.get_pos()):
                    print("hi")
                    pygame.mixer.music.play()

    if pygame.time.get_ticks() > nBubble:
        nBubble += 5000

        if len(bubbleList) < 10:
            bubbleList.append(Bubble())
        else:
            pass
        
    for b in bubbleList:
        b.move()
    
    pygame.display.update()
    FramePerSec.tick(fps)

I have looked at a couple other similar posts on here and have implemented them as you can probably see. It throws no errors on my computer it just does nothing when clicked.


Solution

  • What are self.x and self.y for? You don't need these attributes. You have self.rect.x and self.rect.y. The collision detection depends on the position stored in the rect attribute.

    if b.rect.collidepoint(pygame.mouse.get_pos()):
    

    However, self.rect.x and self.rect.y do not magically change when you change self.x and self.y. The position stored in the rect attribute is not tied to self.x and self.y. Get rid of self.x and self.y:

    class Bubble(pygame.sprite.Sprite):
       def __init__(self):
    
           self.radius = random.randint(50,100)
           self.image = pygame.Surface([self.radius/2,self.radius/2])
           self.image.fill(blue)
           self.image = pygame.image.load(bPath+"Images\\Bubble.png")
           self.rect = self.image.get_rect()
           self.bx = random.randint(70, 1466)
           self.way = 0
           self.rect.x = self.bx
           self.rect.y = 930
    
       def move(self):
           pygame.draw.circle(tv, blue, self.rect.center, self.radius)
           
           self.rect.y -= 2
           if self.rect.x == self.bx+20:
               self.way = 1
           elif self.rect.x == self.bx-20:
               self.way = 0
           else:
               pass
    
           if self.way == 0:
               self.rect.x += 1
           else:
               self.rect.x -= 1
    
           if self.rect.y <= 0:
               self.bx = random.randint(70, 1466)
               self.rect.x = self.bx
               self.rect.y = 930
               self.radius=random.randint(50,100)
           else:
               pass
    

    See also How do I detect collision in pygame?.