Глава 21 · Проект: космический шутер

Попадания во врагов и начисление очков

groupcollide() проверяет столкновения целых групп одним вызовом — но очки нужно начислять аккуратно.

Раздел 21.6 проверял столкновения пуль и врагов вручную, вложенными циклами по спискам. Группы спрайтов (раздел 21.9) решают эту же задачу одним вызовом:

fragment_bullet_enemy_collisions.py
def resolve_bullet_enemy_collisions(self):
    collisions = pygame.sprite.groupcollide(self.bullets, self.enemies, True, True)
    destroyed = {{vrag for vragi in collisions.values() for vrag in vragi}}
    for vrag in destroyed:
        self._spawn_explosion(vrag.rect.center)
    return ochki_za_unichtozhennyh(destroyed)

pygame.sprite.groupcollide(a, b, True, True) сравнивает каждый спрайт из a с каждым спрайтом из b и возвращает словарь: пуля → список врагов, которых она задела. Оба флага True означают «удалить из своей группы при столкновении» — сама группа берёт на себя ту же задачу, что вручную решали новые списки в разделе 21.6.

Реальное окно: вспышка взрыва там, где пуля попала во врага, счёт вверху увеличился
Реальное окно — момент попадания: и пуля, и враг уже удалены из своих групп, взрыв запущен.
Почему подсчёт очков идёт через set, а не через сумму по всем парам
Если сразу несколько пуль задели одного и того же врага в одном обновлении, groupcollide() вернёт этого врага в списках для каждой из них — но физически это один и тот же уничтоженный враг. Собирая всех задетых врагов в множество (set) перед подсчётом очков, каждый враг засчитывается ровно один раз, сколько бы пуль его ни задели одновременно.
Практика: столкновения и подсчёт очков
Проверяется прямо в браузере — установка Pygame не требуется
Практика выполняется локально
Открыть практику →