Menu
CoddyTech

Camera mượt mà

Thuộc phần Âm thanh và cảm giác chơi trong hành trình Pygame của Coddy. Bài học 17 trên 23.

Camera trong trò chơi đường đua này luôn gắn chặt với người chơi: người chơi làm gì thì họ vẫn ở giữa màn hình, còn thế giới trượt bên dưới. Cách này hiệu quả, nhưng mỗi lần bắt đầu và dừng lại đều khiến toàn bộ khung hình giật mạnh.

Để camera bám theo với độ mượt giống như vòng tròn. Vị trí đích là vị trí giúp người chơi nằm giữa màn hình:

camera_x += (player.centerx - 240 - camera_x) * 0.1
camera_x = max(0, min(camera_x, WORLD_WIDTH - 480))

Người chơi di chuyển như trước, chỉ có khung hình chuyển động mượt hơn. Khi người chơi bắt đầu chạy, camera hơi trễ lại, nên người chơi chạy lên phía trước tâm màn hình. Khi họ dừng lại, camera lướt tới để bắt kịp rồi dừng lại khi người chơi một lần nữa ở giữa màn hình. Dòng thứ hai vẫn giữ camera trong phạm vi thế giới.

Thế giới vẫn được vẽ tại -int(camera_x) như trước. Bây giờ, camera_x là một số thập phân; int() giúp hình ảnh được vẽ ở vị trí pixel nguyên, còn biến này giữ nguyên giá trị chính xác cho khung hình tiếp theo.

Một bảng menu trượt vào, một thanh máu giảm dần, một điểm số tăng lên: mọi thứ di chuyển đến một giá trị mới đều có thể chuyển động mượt theo cách tương tự.

challenge icon

Thử thách

Trung bình

Giúp camera bám theo một cách mượt mà.

  1. Thay camera_x = player.centerx - 240 bằng một dòng lệnh di chuyển camera_x một phần mười quãng đường hướng tới player.centerx - 240 trong mỗi khung hình.
  2. Giữ lại dòng lệnh giới hạn giá trị của nó.

Nhấn “Chơi” rồi chạy sang phải: camera sẽ theo sau, sau đó bắt kịp. Tiếp theo, nhấn “Kiểm tra”.

Tự làm thử

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Long Road")
clock = pygame.time.Clock()

WORLD_WIDTH = 1440
player = pygame.Rect(220, 240, 40, 40)
camera_x = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.x -= 6
    if keys[pygame.K_RIGHT]:
        player.x += 6
    player.left = max(player.left, 0)
    player.right = min(player.right, WORLD_WIDTH)

    camera_x = player.centerx - 240
    camera_x = max(0, min(camera_x, WORLD_WIDTH - 480))

    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (80, 80, 100), (0, 280, 480, 80))
    for post_x in range(0, WORLD_WIDTH, 120):
        pygame.draw.rect(screen, (80, 160, 255), (post_x - int(camera_x), 220, 20, 60))
    pygame.draw.rect(screen, (90, 200, 120), player.move(-int(camera_x), 0))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Âm thanh và cảm giác chơi

Tự luyện tập: Playground Pygame