I am doing a balloon popping game and would like the balloons to disappear when clicked. I have an explosion class and an event in the main loop that correctly checks the position of a sprite and then shows an explosion animation if the mouse clicks a balloon. Despite this the original balloon sprite keeps falling down the screen.
HERE IS THE BALLOON CLASS
class Balloon(pygame.sprite.Sprite):
def __init__(self,img):
super(Balloon,self).__init__()
self.image=pygame.image.load(img).convert_alpha()
self.image=pygame.transform.scale(self.image,(40,40))
self.speed = random.randint(1,4)
self.rect=self.image.get_rect()
self.rect.x= random.randrange(screen_width)
self.rect.y= 0
def update(self):
for event in pygame.event.get():
if event.type==pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
for sprite in balloongroup:
if sprite.rect.collidepoint(pos):
self.kill()
self.rect.y+=self.speed
if self.rect.bottom >screen_height:
self.kill()
NOW HERE IS THE MAIN LOOP:
def start():
#explosion_group.update()
#explosion_group.empty()
balloongroup.empty()
allsprites.empty()
#basket=createBasket()
while True:
clock.tick(fps)
for event in pygame.event.get():
if event.type==QUIT:
return
explosion_group.update()
if event.type==pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
for sprite in balloongroup:
if sprite.rect.collidepoint(pos):
explosion = Explosion(pos[0], pos[1])
explosion_group.add(explosion)
allsprites.add(explosion)
explosion_group.draw(screen)
screen.fill((0,0,0)) # <--------------- here
screen.blit(pygame.image.load("background.jpg"),(0,0))
balloongroup.update()
if random.randrange(100)<2:
create_balloon()
allsprites.draw(screen)
clock.tick(60)
pygame.display.update()
I thought adding the event in the update method for the balloon class would work but alas it does not. I’m not sure where else to start.
>Solution :
First, notice that your event loop is incorrect. You must handle all the event sin the loop:
def start():
# [...]
while True:
# [...]
for event in pygame.event.get():
if event.type == QUIT:
return
if event.type == pygame.MOUSEBUTTONDOWN:
for sprite in balloongroup:
if sprite.rect.collidepoint(event.pos):
explosion = Explosion(*event.pos)
explosion_group.add(explosion)
allsprites.add(explosion)
explosion_group.draw(screen)
explosion_group.update()
Never call pygame.event.get() more than once in the application loop. See Faster version of ‘pygame.event.get()’. Why are events being missed and why are the events delayed?.
Why don’t you show the explosion instead of the sprite? kill the sprite when the blast object is created:
def start():
# [...]
while True:
# [...]
for event in pygame.event.get():
if event.type == QUIT:
return
if event.type == pygame.MOUSEBUTTONDOWN:
for sprite in balloongroup:
if sprite.rect.collidepoint(event.pos):
srite.kill() # <----------
explosion = Explosion(event.pos[0], event.pos[1])
# [...]
Alternatively you can kill the sprite at the end of the explosion animation. Pass the sprite on to the explosion class and kill it when the animation ends:
class Explosion(pygame.sprite.Sprite):
def __init__(self, x, y, target):
pygame.sprite.Sprite.__init__(self)
# [...]
self.target = target
def update(self):
# [...]
if self.index < len(self.red):
self.image = self.red[self.index]
else:
self.kill()
self.target.kill()
def start():
# [...]
while True:
# [...]
for event in pygame.event.get():
if event.type == QUIT:
return
if event.type == pygame.MOUSEBUTTONDOWN:
for sprite in balloongroup:
if sprite.rect.collidepoint(event.pos):
explosion = Explosion(event.pos[0], event.pos[1], sprite) # <---