Menu
CoddyTech

Poruszanie się w kierunku celu

Część sekcji Dźwięk i odczucia z gry ścieżki Pygame w Coddy. Lekcja 16 z 23.

Kliknij, a kółko teleportuje się w to miejsce. Obiekt, który płynnie przesuwa się na miejsce, wygląda lepiej: najpierw szybko, potem coraz wolniej, aż delikatnie zatrzymuje się w docelowym punkcie. Jedna linijka to załatwia. W każdej klatce przesuń obiekt o część pozostałej odległości:

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

target_x - x to odległość, którą trzeba jeszcze pokonać. Przesunięcie o jedną dziesiątą tej odległości pozwala pokonać w pierwszej klatce 20 pikseli z 200-pikselowej drogi. W następnej klatce pozostaje 180 pikseli, więc obiekt przesuwa się o 18, potem o 16.2 i tak dalej. Kroki maleją, gdy kółko zbliża się do celu: ruch łagodnie wyhamowuje, zamiast nagle się zatrzymać.

To często nazywa się lerp, skrótem od interpolacji liniowej. Ułamek określa charakter ruchu: 0.1 oznacza płynny ruch, 0.3 — żwawy, a 0.02 — powolny i lekki. Obiekt nigdy nie trafia dokładnie w cel, ale po sekundzie znajduje się w odległości mniejszej niż jeden piksel, czego nikt nie zauważy.

Przechowuj x i y jako liczby dziesiętne we własnych zmiennych. Rect przechowuje liczby całkowite, więc przesunięcie o 0.4 piksela zostałoby zaokrąglone do 0, a ruch zatrzymałby się przed celem.

challenge icon

Wyzwanie

Łatwy

Okrąg przeskakuje do każdego kliknięcia. Spraw, by płynnie się przesuwał: zastąp x = target_x i y = target_y wierszami, które w każdej klatce przesuwają x i y o jedną dziesiątą drogi do celu.

Spróbuj swoich sił

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()

Wszystkie lekcje w sekcji Dźwięk i odczucia z gry

Poćwicz samodzielnie: Edytor online Pygame