Group Against Group
Part of the Sprites and Images section of Coddy's Pygame journey. Lesson 20 of 36.
Lasers should destroy enemies. That is a group against a group: any laser against any enemy. groupcollide tests every pair at once:
hits = pygame.sprite.groupcollide(enemies, lasers, True, True)
score += len(hits)The two Trues are the dokill flags, one per group: the first kills the enemies that were hit, the second the lasers that hit them. A laser that goes on flying after a hit could take out a second enemy above the first.
hits is a dictionary: each enemy that was hit is a key, and its value is the list of lasers that hit it. len(hits) is the number of enemies hit this frame, even when two lasers hit the same one.
The order of the groups decides what the keys are. With groupcollide(lasers, enemies, True, True) the keys would be lasers, and len(hits) would count lasers instead.
Challenge
Medium- After the updates, test
enemiesagainstlaserswithpygame.sprite.groupcollide, killing both the enemy and the laser. - Add the number of enemies hit to
score.
Try it yourself
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Laser Hits")
clock = pygame.time.Clock()
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
enemy_image = pygame.image.load("assets/images/enemy_red.png").convert_alpha()
laser_image = pygame.image.load("assets/images/laser.png").convert_alpha()
font = pygame.font.Font(None, 32)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(midbottom=(320, 470))
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 6
if keys[pygame.K_RIGHT]:
self.rect.x += 6
self.rect.clamp_ip(screen.get_rect())
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = enemy_image
self.rect = self.image.get_rect(center=(x, y))
def update(self):
self.rect.y += 1
if self.rect.top > 480:
self.rect.bottom = 0
class Laser(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = laser_image
self.rect = self.image.get_rect(midbottom=(x, y))
def update(self):
self.rect.y -= 10
if self.rect.bottom < 0:
self.kill()
player = Player()
lasers = pygame.sprite.Group()
enemies = pygame.sprite.Group()
for i in range(5):
enemies.add(Enemy(64 + i * 128, 60))
score = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
lasers.add(Laser(player.rect.centerx, player.rect.top))
player.update()
lasers.update()
enemies.update()
screen.fill((20, 22, 40))
enemies.draw(screen)
lasers.draw(screen)
screen.blit(player.image, player.rect)
text = font.render(f"Score: {score}", True, (240, 240, 240))
screen.blit(text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Sprites and Images
4Sprites and Groups
The Sprite ClassGroupsRemove with kill()Catch with spritecollideGroup Against Group3Classes for Game Objects
Your First ClassMethodsSelf Is the ObjectA List of ObjectsObjects with ImagesA SubclassPractice on your own: Pygame playground