Столкновения
В любой игре нужно понимать, что с чем столкнулось: игрок с монетой, пуля с врагом, мяч со стеной, курсор с кнопкой. В pygame это делает Rect.
Точка и прямоугольник
button = pygame.Rect(100, 50, 200, 60)
print(button.collidepoint(150, 80)) # True — точка внутри
print(button.collidepoint((300, 80))) # False — x = 300 уже снаружи
Прямоугольник (x, y, w, h) содержит точки с x от x до x + w - 1 и y от y до y + h - 1. Значит, right и bottom — это первая координата за прямоугольником. Это частый источник ошибок «на один пиксель», если сравнивать вручную.
Клик мышью — событие MOUSEBUTTONDOWN с полем event.pos, а текущее положение курсора — pygame.mouse.get_pos().
Два прямоугольника
player.colliderect(coin) # пересекаются ли
player.contains(coin) # лежит ли coin целиком внутри player
Прямоугольники, которые только касаются сторонами, не пересекаются.
Один со многими
i = player.collidelist(coins) # номер первой монеты, которой касается игрок, или -1
hits = player.collidelistall(coins) # номера всех таких монет
Удаление из списка
Собранные монеты нужно убрать, но удалять из списка внутри цикла по нему нельзя — цикл перескочит через элемент:
for coin in coins: # ошибка: после remove следующая монета пропускается
if player.colliderect(coin):
coins.remove(coin)
Правильно — построить новый список тех, что остаются:
coins[:] = [c for c in coins if not player.colliderect(c)]
Запись coins[:] = … меняет тот же список, который передали в функцию. А coins = […] внутри функции создаст новый список только в ней — снаружи монеты не исчезнут.
Отскок
Отскок — это смена знака скорости. Но если просто писать vx = -vx, мяч, оказавшийся за стеной (быстро влетел или его там подали), будет каждый кадр менять направление и «дрожать». Надёжнее задавать направление явно:
if ball.left <= field.left:
vx = abs(vx) # от левой стены — всегда вправо
if ball.right >= field.right:
vx = -abs(vx) # от правой — всегда влево
То же для ракетки: отражать мяч, только если он летит к ней (vy > 0), иначе он «застрянет» внутри.
Итог
collidepoint— точка,colliderect— прямоугольник;rightиbottomуже снаружи;collidelist— первый,collidelistall— все;- не удаляйте из списка в цикле по нему;
lst[:] = …меняет переданный список; - отскок: задавайте направление через
abs, а не переворачивайте знак.