Menu
CoddyTech

Đệm lệnh nhảy

Thuộc phần Thế giới trò chơi trong hành trình Pygame của Coddy. Bài học 14 trên 36.

Người chơi nhấn nút nhảy khi thấy nhân vật sắp tiếp đất, thường là sớm hơn vài khung hình. Khi lệnh nhảy nằm trong sự kiện KEYDOWN, lần nhấn đó xảy ra lúc nhân vật đang ở trên không nên không có tác dụng. Người chơi cảm thấy trò chơi phớt lờ mình.

Bộ đệm nhảy ghi nhớ lần nhấn trong vài khung hình. Sự kiện chỉ khởi động bộ đếm thời gian:

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

Ở mỗi khung hình, trước khi áp dụng trọng lực, hãy nhảy nếu bộ đếm thời gian vẫn đang chạy và nhân vật đang ở trên mặt đất, rồi giảm bộ đếm:

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

Với JUMP_BUFFER = 6, lần nhấn được tính trong 6 khung hình, tức một phần mười giây: đủ lâu để ghi nhận lần nhấn sớm, nhưng đủ ngắn để lần nhấn từ lâu trước khi tiếp đất không khiến nhân vật bất ngờ nhảy. Nếu nhấn khi nhân vật đang ở trên mặt đất, nhân vật vẫn nhảy ở khung hình tiếp theo.

challenge icon

Thử thách

Khó

Chấp nhận lần nhấn nhảy ngay trước khi tiếp đất.

  1. Thêm JUMP_BUFFER = 6 và đặt jump_timer = 0 trước vòng lặp.
  2. Sự kiện KEYDOWN khi nhấn Space hoặc Up sẽ đặt jump_timer = JUMP_BUFFER thay vì nhảy.
  3. Trước khi áp dụng trọng lực: nếu jump_timer > 0 và on_ground, đặt vel_y = JUMP và jump_timer = 0. Sau đó giảm jump_timer đi 1 khi giá trị này lớn hơn 0.

Nhấn Chơi rồi nhấn Space ngay trước khi tiếp đất: nhân vật sẽ nhảy lần nữa. Sau đó nhấn Kiểm tra.

Tự làm thử

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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Thế giới trò chơi

Tự luyện tập: Playground Pygame