Два шарика движутся со случайной скоростью по случайной траектории, отскакивают от стенок окна, а при их столкновении появляется третий шар, который при этом получает новые параметры движения.

В этой программе есть звук, движущиеся графические объекты и обнаружение столкновений.

#!/usr/bin/python3

"""
 Два шарика движутся со случайной скорости по случайной траектории,
 отскакивают от стенок окна, а при их стокновении появляется третий шар,
 при этом новый шар получает случайным образом новые параметры движения,
 а один из предыдущих шаров уходит с поля.
 Стокновения сопровождаются звуком.
"""

import pygame, sys, random
from pygame.locals import *

pygame.mixer.init(48000, -8, 2, 64)
sound = pygame.mixer.Sound(file='click.wav')
pygame.init()
FPS = 100
fpsClock = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((800, 600), 0, 32)
ball1Img = pygame.image.load('blue.png')
x1 = y1 = x2 = y2 = 200                                # координаты
x3 = y3 = 500
xv1 = yv1 = xv2 = yv2 = xv3 = yv3 = 4                  # скорость
check = parity = False

while True:
    fpsClock.tick(FPS)
    DISPLAYSURF.fill((255, 255, 200))
    DISPLAYSURF.blit(ball1Img, (x1, y1))
    DISPLAYSURF.blit(ball1Img, (x2, y2))
    DISPLAYSURF.blit(ball1Img, (x3, y3))
    pygame.display.update()
    x1 += xv1
    y1 += yv1
    xv1 = -xv1 if (x1 > 800-49 or x1 < 0) else xv1    # отскок
    yv1 = -yv1 if (y1 > 600-49 or y1 < 0) else yv1    # от стенок
    x2 += xv2
    y2 += yv2
    xv2 = -xv2 if (x2 > 800-49 or x2 < 0) else xv2
    yv2 = -yv2 if (y2 > 600-49 or y2 < 0) else yv2
    x3 += xv3
    y3 += yv3
    if (x3 > 800-49 or x3 < 0) or (y3 > 600-49 or y3 < 0) or not (xv3 or yv3):
        check = True                                  # третий шар ушёл или стоит
    if check:
        if (((x2-x1)**2+(y2-y1)**2) < 2500):          # столкновение
            check = False
            sound.play()
            print(x1, ",", y1)
            x3 = x1                                   # на поле появляется третий
            y3 = y1
            xv3 = random.randint(-6 , 6)
            yv3 = random.randint(-6 , 6)
            if parity:                                # обновить первый шар
                xv3, xv1 = xv1, xv3
                yv3, yv1 = yv1, yv3
            else:                                     # обновить второй шар
                xv3, xv2 = xv2, xv3
                yv3, yv2 = yv2, yv3
            parity = not parity

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

Размер шарика 50 x 50 px. Wave файл со звуком отскока металлического шарика взят из интернета.

Шарик можно скачать прямо с сайта.

Файл click.wav ссылка для скачивания

Глядя на эти шарики, конкретно залипаешь. Перефразируя поговорку скажем так: "Можно бесконечно смотреть как 22 человека бесцельно в пределах прямоугольника гоняют 1 мяч, но ещё интереснее смотреть как хаотично движутся и беспорядочно сталкиваются два шара в окне этой программы."

Питон столкновения