Menu
CoddyTech

Tiếp đất trên các bệ

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

Giờ hãy để tường đỡ nhân vật. Sau khi sửa chuyển động ngang, hãy di chuyển theo trục y và sửa chuyển động đó theo cách tương tự: nếu nhân vật chồng lên tường khi đang rơi, hãy đặt chân nhân vật lên mép trên của tường.

vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
    if player.colliderect(wall):
        if vel_y > 0:
            player.bottom = wall.top
            vel_y = 0
            on_ground = True

on_ground bắt đầu mỗi khung hình với giá trị False và chỉ chuyển thành True khi nhân vật tiếp đất. Nếu bước khỏi mép, ở khung hình tiếp theo, nhân vật sẽ không còn gì bên dưới, vì vậy nó sẽ rơi và không thể nhảy giữa không trung.

Cách này thay thế dòng FLOOR: hàng dưới cùng của bản đồ là mặt đất, giống như mọi bức tường khác. Trọng lực kéo nhân vật lún vào mặt đất 1 pixel mỗi khung hình, rồi phép kiểm tra tiếp đất nâng nhân vật trở lại, nhờ đó nhân vật đứng yên.

challenge icon

Thử thách

Trung bình

Cho nhân vật tiếp đất trên các bệ.

  1. Xóa dòng kiểm tra FLOOR.
  2. Sau player.y += vel_y, đặt on_ground = False, rồi lặp qua walls.
  3. Với mỗi bức tường mà nhân vật va chạm khi vel_y > 0: player.bottom = wall.top, vel_y = 0, on_ground = True.

Nhấn Chơi: nhân vật tiếp đất trên bệ bên dưới. Sau đó nhấn Kiểm tra.

Tự làm thử

import pygame

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

LEVEL = [
    "................",
    "................",
    "................",
    "....P.....###...",
    "................",
    "................",
    "...####.........",
    "............#...",
    "#.......#...#..#",
    "################",
]

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

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

walls = []
for row, line in enumerate(LEVEL):
    for col, char in enumerate(line):
        if char == "#":
            walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
        elif char == "P":
            start = (col * TILE + TILE // 2, row * TILE + TILE)

player = player_img.get_rect(midbottom=start)
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()
    dx = 0
    if keys[pygame.K_LEFT]:
        dx -= SPEED
    if keys[pygame.K_RIGHT]:
        dx += SPEED

    player.x += dx
    for wall in walls:
        if player.colliderect(wall):
            if dx > 0:
                player.right = wall.left
            elif dx < 0:
                player.left = wall.right

    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 wall in walls:
        screen.blit(block_img, wall)
    screen.blit(player_img, player)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

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

Tự luyện tập: Playground Pygame