Pygame provides several built-in functions for detecting collisions between game objects. These are invaluable because working out exactly when and how moving objects overlap can be a complicated task.

Learn how to add basic physics and collisions in your game using the pygame module.

Pygame’s Built-In Collision Detection Functions

The most basic built-in collision detection function is spritecollide. It takes in a sprite, a group of sprites, and a boolean value indicating whether or not the sprites should "die" (be removed) when they collide. This function returns a list of sprites that have collided. Here is an example of how to use it:

        collided_sprites = pygame.sprite.spritecollide(sprite1, sprite_group, True)
    

Another useful collision detection function is groupcollide, which takes in two groups of sprites and a boolean value as well. This function returns a dictionary with the collided sprites as the keys and the sprites they collided with as the values. Here's an example of how to use it:

        collision_dict = pygame.sprite.groupcollide(group1, group2, True, True)
    

Creating a Basic Platformer Game Using the spritecollide Function

To create a basic platformer game using Pygame, you will need to create a player sprite that the user can control and a platform sprite for the player to stand on. You can use the spritecollide function to detect when the player sprite collides with the platform sprite and prevent the player from falling through the platform.

To start, install the pygame module using pip:

        pip install pygame
    

After that, create simple classes for the Player and Platform, both of which should inherit from Pygame’s Sprite class. The Player class should have an update method to handle the position of the player based on the velocity. Also, it should have a y_velocity variable to apply the gravity effect. The Platform class should have an __init__ method that takes the coordinates of the platform and creates a surface with that size.

Player Class

You can create a Player class using the pygame.sprite.Sprite module. This class will initialize the player with a given x and y coordinates. Then, the update method will update the position of the player by incrementing the y_velocity value.

        import pygame

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.y_velocity = 0

    def update(self):
        self.rect.y += self.y_velocity

Platform Class

The Platform class also uses the pygame.sprite.Sprite module. This class will initialize the platform with given x and y coordinates, as well as a width and height.

        class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface((width, height))
        self.rect = self.image.get_rect(topleft=(x, y))

The Game Loop

The game loop will allow you to create a window with a size of 640x480. Then, it will run a loop that will check for any events, such as a quit command. It will also check for any collisions between the player and the platform. Finally, it will fill the screen with a white color, draw the player and platform, and then flip the display.

        player = Player(100, 300)
player_group = pygame.sprite.Group()
player_group.add(player)

platform = Platform(50, 400, 100, 20)
platform_group = pygame.sprite.Group()
platform_group.add(platform)

# Initialize pygame and create window
pygame.init()
screen = pygame.display.set_mode((640, 480))

# Main game loop
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
    player_group.update()
    collided = pygame.sprite.spritecollide(player, platform_group, False)

    if collided:
        player.y_velocity = 0
    screen.fill((255, 255, 255))
    player_group.draw(screen)
    platform_group.draw(screen)
    pygame.display.flip()

pygame.quit()

Below is the output:

simple platformer game using pygame

Implementing Gravity and Jumping Behavior

To implement gravity and jumping behavior in your platformer game, you will need to add a y velocity to your player sprite and update its y position in each frame. To do this you can use the update method inside the Player class and add the following code snippet:

        class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.y_velocity = 0

    def update(self):
        self.rect.y += self.y_velocity
        self.y_velocity += GRAVITY # Apply gravity to y velocity

Now every time you call the update method, it will update the player position according to its velocity and gravity.

To make the player sprite jump, you can bind the jumping action to a specific key or button and update the player's y velocity with a negative value. The following code snippet is an example of how to jump when a player presses the spacebar.

        JUMP_VELOCITY = -10

# inside the game loop
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
    player.y_velocity = JUMP_VELOCITY

Note that you will need to check the event.type to make sure that the event is a KEYDOWN event before checking the key value.

Adding Basic Physics Such as Friction and Acceleration

To add basic physics such as friction and acceleration to your platformer game, you will need to update the x velocity of your player sprite in each frame. You can add x velocity to the player class and update it in the same way as y velocity. To implement friction, you can decrease the x velocity of the player sprite by a small amount in each frame. For example, you can add the following code snippet inside the update method of the Player class:

        FRICTION = 0.9

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.y_velocity = 0
        self.x_velocity = 0

    def update(self):
        self.rect.y += self.y_velocity
        self.rect.x += self.x_velocity
        self.y_velocity += GRAVITY # Apply gravity to y velocity
        self.x_velocity *= FRICTION # Apply friction to x velocity

To implement acceleration, you can set a variable, player_movement, for the horizontal movement, and update the x velocity of the player sprite according to the player_movement value. You can do this by binding the movement to specific keys or buttons and updating the player's x velocity in the event loop, for example:

        ACCELERATION = 0.5
player_movement = 0

if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_LEFT:
        player_movement = -1
    elif event.key == pygame.K_RIGHT:
        player_movement = 1
elif event.type == pygame.KEYUP:
    if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
        player_movement = 0
        
player.x_velocity += player_movement * ACCELERATION

By using these techniques, you can create a simple yet fun platformer game using Pygame's built-in collision detection functions and basic physics. With a little bit of creativity and experimentation, you can use these techniques to create a variety of different games and game mechanics.

You can find the complete code in the GitHub repository.

Below is the output:

simple platformer game with gravity and acceleration

Improve User Engagement With Collisions

Many games require some form of collision detection. You can use collisions to create a wide range of game mechanics, from simple platformers to complex physics-based simulations.

Implementing basic physics such as gravity, friction, and acceleration can also greatly improve user engagement, adding realism and a sense of weight to game objects.