Menu
CoddyTech

Di chuyển về phía mục tiêu

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 16 trên 23.

Nhấp vào đâu, vòng tròn dịch chuyển tức thời đến đó. Một vật thể trượt vào vị trí trông sẽ đẹp hơn: ban đầu nhanh, sau đó chậm dần và nhẹ nhàng dừng lại. Chỉ cần một dòng lệnh để làm điều đó. Ở mỗi khung hình, hãy di chuyển một phần quãng đường còn lại:

x += (target_x - x) * 0.1
y += (target_y - y) * 0.1

target_x - x là khoảng cách còn lại. Di chuyển một phần mười khoảng cách đó sẽ đi được 20 pixel trong quãng đường dài 200 pixel ở khung hình đầu tiên. Ở khung hình tiếp theo, còn lại 180 pixel, nên nó di chuyển 18, rồi 16.2, cứ thế tiếp tục. Các bước di chuyển ngắn dần khi vòng tròn đến gần: nó chậm lại thay vì dừng đột ngột.

Kiểu chuyển động này thường được gọi là lerp, viết tắt của nội suy tuyến tính (linear interpolation). Tỷ lệ quyết định cảm giác chuyển động: 0.1 cho chuyển động mượt mà, 0.3 cho chuyển động nhanh gọn, 0.02 cho chuyển động chậm và nhẹ bẫng. Vòng tròn không bao giờ đến chính xác đích, nhưng sau một giây, nó cách đích chưa đến một pixel, một khoảng cách không ai nhìn thấy được.

Hãy lưu x và y thành số thập phân trong các biến riêng. Rect lưu số nguyên, nên một bước di chuyển 0.4 pixel sẽ bị làm tròn xuống 0 và vòng tròn sẽ dừng trước đích.

challenge icon

Thử thách

Dễ

Giúp hình tròn lướt đến từng vị trí bạn nhấp.

  1. Tìm x = target_x và y = target_y.
  2. Thay chúng bằng các dòng lệnh đưa x và y tiến một phần mười quãng đường đến mục tiêu trong mỗi khung hình.

Nhấn "Chơi" rồi nhấp chuột: hình tròn sẽ trượt đến đó và chậm dần khi đến nơi. Sau đó, nhấn "Kiểm tra".

Tự làm thử

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Follow the Click")
clock = pygame.time.Clock()

x, y = 240, 180
target_x, target_y = 240, 180

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            target_x, target_y = event.pos

    x = target_x
    y = target_y

    screen.fill((30, 30, 46))
    pygame.draw.line(screen, (90, 90, 110), (target_x - 8, target_y), (target_x + 8, target_y), 2)
    pygame.draw.line(screen, (90, 90, 110), (target_x, target_y - 8), (target_x, target_y + 8), 2)
    pygame.draw.circle(screen, (80, 200, 220), (x, y), 12)
    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