Đụng đầu
Thuộc phần Thế giới trò chơi trong hành trình Pygame của Coddy. Bài học 17 trên 36.
Nhảy từ dưới lên một bệ, nhân vật đi xuyên qua bệ rồi đáp xuống phía trên. Bệ vững chắc sẽ chặn đầu nhân vật. Khi đi lên, vel_y là số âm, vậy nên hãy thêm trường hợp còn lại vào vòng lặp dọc:
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
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0Đầu nhân vật chạm đáy của bức tường, và tốc độ trở thành 0 trong cả hai trường hợp. Sau khi va vào bệ, trọng lực lập tức khiến nhân vật rơi xuống. Nếu không có vel_y = 0, nhân vật sẽ tiếp tục cố đi lên và mắc kẹt bên dưới bệ cho đến khi trọng lực triệt tiêu cú nhảy.
Dấu của vel_y cho biết nhân vật đi từ phía nào, giống như dx với các bức tường: khi rơi, nhân vật va vào mặt trên của tường; khi đi lên, nhân vật va vào mặt dưới.
Thử thách
DễDừng cú nhảy khi đầu va vào bệ.
- Trong vòng lặp xử lý va chạm theo chiều dọc, thêm trường hợp
vel_y < 0:player.top = wall.bottom. - Đặt
vel_y = 0sau cả hai trường hợp để cú va đầu làm nhân vật ngừng bay lên.
Nhấn Chơi rồi nhảy: đầu nhân vật dừng lại bên dưới bệ phía trên. Sau đó nhấn Kiểm tra.
Tự làm thử
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("Head Bump")
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
for wall in walls:
if player.colliderect(wall):
if vel_y > 0:
player.bottom = wall.top
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
1Bản đồ dạng văn bản
Một màn chơi bằng văn bảnHàng và cộtCác chữ cái mang ý nghĩaNơi người chơi bắt đầuTừng màn hình một4Va chạm với các bệ
Tường bên trái và bên phảiTiếp đất trên các bệĐụng đầuRơi khỏi màn chơiTừng trục mộtTự luyện tập: Playground Pygame