Menu
CoddyTech

Pop on Pickup

Part of the Sound and Game Feel section of Coddy's Pygame journey. Lesson 18 of 23.

When you collect a gem, the score goes up by one, but your eye is on the gem, not on the corner. A short pop pulls the eye to the counter: the icon jumps bigger, then shrinks back to its size.

Keep a scale, 1.0 for normal size. A pickup sets it to 1.6; each frame it eases back toward 1 with the same line as before:

pop = 1.6         # when a gem is collected

pop += (1 - pop) * 0.2    # every frame

When drawing, the scale sets the size. Build the Rect at that size and then put its centre in place, so the icon grows around its middle instead of from its corner:

size = int(20 * pop)
icon = pygame.Rect(0, 0, size, size)
icon.center = (30, 30)

The jump is instant and the way back is eased. That is what reads as a pop: a 0.2 fraction brings it back in about a quarter of a second.

For an image, scale it with pygame.transform.scale_by(image, pop) and centre its Rect the same way.

challenge icon

Challenge

Easy

Click the purple gem to collect it. Make the gold icon pop:

  1. Make pop = 1.0 before the loop.
  2. Set pop = 1.6 when a gem is collected.
  3. Each frame, ease it back: pop += (1 - pop) * 0.2.
  4. Draw the icon int(20 * pop) pixels wide and high, still centred at (30, 30).

Try it yourself

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Gem Picker")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)

coin_sound = pygame.mixer.Sound("assets/sounds/coin.ogg")
gem = pygame.Rect(300, 200, 24, 24)
score = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN and gem.collidepoint(event.pos):
            score += 1
            coin_sound.play()
            gem.topleft = (random.randint(80, 420), random.randint(90, 300))

    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (170, 90, 230), gem)
    icon = pygame.Rect(0, 0, 20, 20)
    icon.center = (30, 30)
    pygame.draw.rect(screen, (255, 200, 60), icon)
    label = font.render(f"x {score}", True, (240, 240, 240))
    screen.blit(label, (52, 20))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

All lessons in Sound and Game Feel

Practice on your own: Pygame playground