Menu
CoddyTech

A Top Falling Speed

Part of the Worlds section of Coddy's Pygame journey. Lesson 13 of 35.

Gravity keeps adding to the falling speed. Drop from high enough and the player moves 30 or 40 pixels in one frame. A tile is 36 pixels tall, so at that speed the player can pass right through a platform between two frames, without ever overlapping it.

Real falls have a top speed too. Cap the speed with min:

MAX_FALL = 12
# in the loop
vel_y = min(vel_y + GRAVITY, MAX_FALL)

min gives the smaller of its two numbers, so the speed grows by 1 a frame until it reaches 12 and then stays there. A jump starts at -15, below the cap, so jumps do not change.

Twelve is a third of a tile: whatever the player falls onto, some frame overlaps it, and the landing test can catch it.

challenge icon

Challenge

Easy
  1. Add MAX_FALL = 12 at the top.
  2. Replace vel_y += GRAVITY with vel_y = min(vel_y + GRAVITY, MAX_FALL).

The player starts in the air, so you can see it reach the top speed.

Try it yourself

import pygame

TILE = 36
FLOOR = 324
GRAVITY = 1
JUMP = -15

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Falling Speed")
clock = pygame.time.Clock()

background = pygame.image.load("assets/backgrounds/clouds.png").convert_alpha()
grass_img = pygame.image.load("assets/images/grass.png").convert_alpha()
player_img = pygame.image.load("assets/images/player.png").convert_alpha()

player = player_img.get_rect(topleft=(264, 40))
vel_y = 0
on_ground = False

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 in (pygame.K_SPACE, pygame.K_UP):
            if on_ground:
                vel_y = JUMP
        elif event.type == pygame.KEYUP and event.key in (pygame.K_SPACE, pygame.K_UP):
            if vel_y < -4:
                vel_y = -4

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.x -= 4
    if keys[pygame.K_RIGHT]:
        player.x += 4

    vel_y += GRAVITY
    player.y += vel_y
    on_ground = False
    if player.bottom > FLOOR:
        player.bottom = FLOOR
        vel_y = 0
        on_ground = True

    for y in range(0, 360, 72):
        for x in range(0, 576, 72):
            screen.blit(background, (x, y))
    for x in range(0, 576, TILE):
        screen.blit(grass_img, (x, FLOOR))
    screen.blit(player_img, player)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

All lessons in Worlds

Practice on your own: Pygame playground