DEV Community

David Newberry
David Newberry

Posted on

Bare-Bones Pygame Platformer Starter

This Python pygame code is based on the JavaScript code and algorithms described in this article.

import pygame

W = 600
H = 300
S = 20

# pygame setup
pygame.init()
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
running = True

# game setup
player = pygame.Rect( (50, 50), (S, S) )
v = pygame.Vector2(0, 0)

g = pygame.Vector2(0, 1)

# platforms

platforms = [
    pygame.Rect((25, 100), (100, 50)),
    pygame.Rect((125, 125), (100, 50))
]

while running:
    # poll for events
    for event in pygame.event.get():
        # pygame.QUIT = user closed window
        if event.type == pygame.QUIT:
            running = False
            break
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
            v.x = -3
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            v.x = 3
        elif event.type == pygame.KEYUP and event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
            v.x = 0
        elif event.type == pygame.KEYUP and event.key == pygame.K_UP and grounded:
            v += pygame.Vector2(0, -10)

    # fill buffer with white
    screen.fill("white")

    # update velocity and position
    v += g
    player.move_ip(v)

    grounded = False

    # platforms
    for platform in platforms:
        screen.fill("black", platform)

        if player.colliderect(platform):
            pMidX = player.centerx
            pMidY = player.centery
            aMidX = platform.centerx
            aMidY = platform.centery

            # To find the side of entry calculate based on
            # the normalized sides
            dx = (aMidX - pMidX) / (platform.width / 2)
            dy = (aMidY - pMidY) / (platform.height / 2)

            # Calculate the absolute change in x and y
            absDX = abs(dx)
            absDY = abs(dy)

            # If the distance between the normalized x and y
            # position is less than a small threshold (.1 in this case)
            # then this object is approaching from a corner
            if abs(absDX - absDY) < 0.1:

                # If the player is approaching from positive X
                if dx < 0:

                    # Set the player x to the right side
                    player.x = platform.right

                # If the player is approaching from negative X
                else:

                    # Set the player x to the left side
                    player.x = platform.left - player.width

                # If the player is approaching from positive Y
                if dy < 0:

                    # Set the player y to the bottom
                    player.y = platform.bottom

                # If the player is approaching from negative Y
                else:

                    # Set the player y to the top
                    player.y = platform.top - player.height

                v.x = 0
                v.y = 0

            # If the object is approaching from the sides
            elif absDX > absDY:

                # If the player is approaching from positive X
                if dx < 0:
                    player.x = platform.right

                else:
                # If the player is approaching from negative X
                    player.x = platform.left - player.width

                # Velocity component
                v.x = 0

            # If this collision is coming from the top or bottom more
            else:

                # If the player is approaching from positive Y
                if dy < 0:
                    player.y = platform.bottom

                else:
                    # If the player is approaching from negative Y
                    player.y = platform.top - player.height

                # Velocity component
                v.y = 0

                # And player is on a platform
                grounded = True

    screen.fill("green", player)

    # copy buffer to screen
    pygame.display.flip()

    # limits FPS
    clock.tick(30)

pygame.quit()

Enter fullscreen mode Exit fullscreen mode

Top comments (0)