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 = 0Stoją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.
Wyzwanie
Średni- Rozdziel ruch:
player.x += dxi pętlę powalls, która koryguje tylko położenie na osi x. - Następnie grawitacja,
player.y += vel_y,on_ground = Falsei 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
1Mapy z tekstu
Poziom w tekścieWiersze i kolumnyLitery ze znaczeniemGdzie zaczyna graczJeden ekran naraz4Kolizje z platformami
Ściany z lewej i prawejLądowanie na platformachUderz głowąWypadanie poza poziomJedna oś narazPoćwicz samodzielnie: Edytor online Pygame