Menu
CoddyTech

Giữ camera trong khung hình

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

Một camera luôn căn giữa người chơi sẽ hiển thị bầu trời bên trái màn chơi lúc bắt đầu và cả bên phải khi kết thúc. Hãy giữ camera trong phạm vi hai mép màn chơi.

Giá trị nhỏ nhất của camera là 0: cửa sổ bắt đầu từ mép trái màn chơi. Giá trị lớn nhất là level_width - WIDTH: mép phải cửa sổ trùng với mép phải màn chơi. Hãy giới hạn giá trị sau khi camera đi theo người chơi:

camera_x = player.centerx - WIDTH // 2
camera_x = max(0, min(camera_x, level_width - WIDTH))

min giảm giá trị camera nếu camera ở quá xa bên phải; max tăng giá trị nếu camera ở quá xa bên trái. Ở giữa màn chơi, cả hai hàm đều không thay đổi gì và camera vẫn đi theo như trước. Gần hai đầu màn chơi, camera dừng lại và người chơi đi về phía mép cửa sổ. Đây là cách hoạt động của hầu hết game cuộn cảnh ngang.

challenge icon

Thử thách

Dễ

Dừng camera ở hai đầu màn chơi.

  1. Tìm dòng camera_x = player.centerx - WIDTH // 2.
  2. Thêm camera_x = max(0, min(camera_x, level_width - WIDTH)) bên dưới.

Nhấn Chơi: lúc bắt đầu, khung nhìn không còn vượt quá mép trái của màn chơi. Sau đó nhấn Kiểm tra.

Tự làm thử

import pygame

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

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

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

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)

level_width = len(LEVEL[0]) * TILE
player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False
camera_x = 0

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
                on_ground = True
            elif vel_y < 0:
                player.top = wall.bottom
            vel_y = 0

    camera_x = player.centerx - WIDTH // 2

    screen.fill((140, 200, 240))
    for wall in walls:
        screen.blit(block_img, (wall.x - camera_x, wall.y))
    screen.blit(player_img, (player.x - camera_x, player.y))
    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