Menu
CoddyTech

A Subclass

Part of the Sprites and Images section of Coddy's Pygame journey. Lesson 15 of 36.

Some enemies should zigzag. They fall like the others and also slide sideways, turning at the window's edges. Copying the whole Enemy class to change one method would mean fixing every bug twice. A subclass takes everything from its parent and changes only what differs:

class Zigzag(Enemy):
    def __init__(self, image, x, y):
        super().__init__(image, x, y)
        self.dx = 3

    def update(self):
        super().update()
        self.rect.x += self.dx
        if self.rect.left < 0 or self.rect.right > 640:
            self.dx = -self.dx

class Zigzag(Enemy) means a Zigzag is an Enemy. It has draw without writing it. Its own update replaces the parent's, and super().update() runs the parent's version first, so the falling and the return to the top are not written twice. super().__init__(...) does the same for setting up.

A Zigzag goes in the same list as the others: the loop calls enemy.update() and each object runs its own kind of update.

challenge icon

Challenge

Medium
  1. Write class Zigzag(Enemy): its __init__ calls super().__init__(image, x, y) and sets self.dx = 3.
  2. Its update calls super().update(), adds self.dx to self.rect.x, and flips the sign of self.dx when the Rect pokes out of the left or right edge.
  3. Make the yellow enemy in enemies a Zigzag; red and green stay Enemy.

Try it yourself

import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Enemy Rain")
clock = pygame.time.Clock()

red = pygame.image.load("assets/images/enemy_red.png").convert_alpha()
green = pygame.image.load("assets/images/enemy_green.png").convert_alpha()
yellow = pygame.image.load("assets/images/enemy_yellow.png").convert_alpha()

class Enemy:
    def __init__(self, image, x, y):
        self.image = image
        self.rect = image.get_rect(center=(x, y))
        self.speed = 2

    def update(self):
        self.rect.y += self.speed
        if self.rect.top > 480:
            self.rect.bottom = 0

    def draw(self, screen):
        screen.blit(self.image, self.rect)


enemies = [Enemy(red, 160, 100), Enemy(green, 320, 100), Enemy(yellow, 480, 100)]

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    for enemy in enemies:
        enemy.update()

    screen.fill((20, 22, 40))
    for enemy in enemies:
        enemy.draw(screen)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Sprites and Images

Practice on your own: Pygame playground