Menu
CoddyTech

Jedna oś naraz

Część sekcji Światy ścieżki Pygame w Coddy. Lekcja 19 z 35.

Twój kod obsługi kolizji przesuwa i koryguje pozycję x, a potem przesuwa i koryguje pozycję y. Ten kod początkowy przesuwa postać w obu osiach i koryguje jej pozycję tylko raz. Uruchom go i idź w prawo: postać gwałtownie cofa się wzdłuż podłoża.

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

Stojąc na ziemi, grawitacja przesuwa postać o 1 piksel w dół, w ziemię, w każdej klatce. Gdy w tej samej klatce porusza się w prawo, postać nachodzi na kafelek podłoża pod sobą, a kod nie potrafi ustalić dlaczego. Widzi dx > 0 i ustawia prawą krawędź postaci przy lewej krawędzi tego kafelka: cofa ją, wzdłuż podłoża.

Jedno nachodzenie, dwa ruchy, brak sposobu, by ustalić, który ruch je spowodował. Przy poruszaniu się wzdłuż jednej osi naraz każde nachodzenie ma jedną przyczynę. Po ruchu wzdłuż osi x postać nie znajduje się jeszcze w ziemi, więc zatrzymują ją tylko prawdziwe ściany. Po ruchu wzdłuż osi y do nachodzenia może dojść tylko w wyniku ruchu wzdłuż osi y.

challenge icon

Wyzwanie

Średni
  1. Rozdziel ruch: player.x += dx i pętlę po walls, która koryguje tylko położenie na osi x.
  2. Następnie grawitacja, player.y += vel_y, on_ground = False i druga pętla, która koryguje tylko położenie na osi y.

Spróbuj swoich sił

import pygame

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

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

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("One Axis at a Time")
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
    vel_y = min(vel_y + GRAVITY, MAX_FALL)
    player.y += vel_y
    on_ground = False
    for wall in walls:
        if player.colliderect(wall):
            if dx > 0:
                player.right = wall.left
            elif dx < 0:
                player.left = wall.right
            if vel_y > 0:
                player.bottom = wall.top
                on_ground = True
            elif vel_y < 0:
                player.top = wall.bottom
            vel_y = 0

    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()

Wszystkie lekcje w sekcji Światy

Poćwicz samodzielnie: Edytor online Pygame