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
Easy- Add
MAX_FALL = 12at the top. - Replace
vel_y += GRAVITYwithvel_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
1Maps from Text
A Level in TextRows and ColumnsLetters With MeaningsWhere the Player StartsOne Screen at a Time3Gravity and Jumping
Falling With GravityJump From the GroundShort HopsA Top Falling SpeedJump BufferPractice on your own: Pygame playground