Satu sumbu setiap kali
Termasuk bagian Dunia Game dalam perjalanan Pygame di Coddy. Pelajaran 19 dari 35.
Kodemu untuk tabrakan menggerakkan dan membetulkan x, lalu menggerakkan dan membetulkan y. Kode awal ini menggerakkan keduanya lalu membetulkannya sekali. Jalankan dan berjalanlah ke kanan: pemain tersentak mundur di sepanjang lantai.
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 = 0Saat berdiri di tanah, gravitasi menggerakkan pemain 1 piksel ke bawah menembus tanah pada setiap frame. Jika bergerak ke kanan pada frame yang sama, pemain bertumpang tindih dengan tile tanah di bawahnya, dan kode tidak bisa mengetahui penyebabnya. Kode melihat dx > 0 lalu menempatkan sisi kanan pemain di sisi kiri tile itu: mundur, di sepanjang lantai.
Satu tumpang tindih, dua gerakan, tidak ada cara untuk mengetahui gerakan mana yang menyebabkannya. Dengan menggerakkan satu sumbu pada satu waktu, setiap tumpang tindih memiliki satu penyebab. Setelah gerakan x, pemain belum berada di dalam tanah, jadi hanya dinding sungguhan yang menghentikannya. Setelah gerakan y, tumpang tindih hanya bisa disebabkan oleh gerakan sepanjang sumbu y.
Tantangan
Sedang- Pisahkan pergerakan:
player.x += dxdan perulangan padawallsyang hanya memperbaiki x. - Lalu gravitasi,
player.y += vel_y,on_ground = Falsedan perulangan kedua yang hanya memperbaiki y.
Coba sendiri
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()
Semua pelajaran di Dunia Game
1Peta dari Teks
Level dalam TeksBaris dan KolomHuruf yang Memiliki MaknaTempat Pemain MemulaiSatu Layar Setiap Kali4Tabrakan dengan Platform
Dinding kiri dan kananMendarat di platformMembentur kepalaJatuh keluar dari levelSatu sumbu setiap kaliLatihan sendiri: Playground Pygame