Menu
CoddyTech

Буфер прыжка

Часть раздела Игровые миры путешествия по Pygame на Coddy. Урок 14 из 35.

Игроки нажимают кнопку прыжка, когда видят, что скоро приземлятся, часто на несколько кадров раньше. Если прыжок обрабатывается в событии KEYDOWN, в момент нажатия игрок ещё находится в воздухе, и нажатие теряется. Игроку кажется, что игра его проигнорировала.

Буфер прыжка запоминает нажатие на несколько кадров. Событие только запускает таймер:

elif event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
    jump_timer = JUMP_BUFFER

Каждый кадр перед применением гравитации выполняй прыжок, если таймер ещё работает и игрок стоит на земле, а затем отсчитывай таймер:

if jump_timer > 0 and on_ground:
    vel_y = JUMP
    jump_timer = 0
if jump_timer > 0:
    jump_timer -= 1

При значении JUMP_BUFFER = 6 нажатие засчитывается в течение 6 кадров — десятой доли секунды: этого достаточно, чтобы учесть раннее нажатие, но недостаточно, чтобы нажатие задолго до приземления неожиданно вызвало прыжок. Нажатие на земле всё равно вызывает прыжок на следующем кадре.

challenge icon

Задание

Сложно
  1. Добавь JUMP_BUFFER = 6 в начало и jump_timer = 0 перед циклом.
  2. При нажатии клавиши Space или Up (KEYDOWN) установи jump_timer = JUMP_BUFFER вместо прыжка.
  3. Каждый кадр перед применением гравитации: если jump_timer > 0 и on_ground, установи vel_y = JUMP и jump_timer = 0. Затем, если jump_timer > 0, вычти из него 1.

Попробуйте сами

import pygame

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

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Jump Buffer")
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 = min(vel_y + GRAVITY, MAX_FALL)
    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()
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Игровые миры

Потренируйтесь самостоятельно: Песочница Pygame