Menu
CoddyTech

Движение к цели

Часть раздела Звук и игровые ощущения путешествия по Pygame на Coddy. Урок 16 из 23.

Щёлкни, и круг мгновенно переместится туда. Объект, плавно скользящий на место, выглядит лучше: сначала быстро, затем медленнее, мягко останавливаясь в нужной точке. Для этого достаточно одной строки. На каждом кадре перемещайся на часть оставшегося расстояния:

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

target_x - x — это расстояние, которое осталось пройти. Перемещение на одну десятую этого расстояния покрывает 20 пикселей из 200 за первый кадр. В следующем кадре останется 180 пикселей, поэтому круг переместится на 18, затем на 16.2 и так далее. Шаги уменьшаются по мере приближения круга: он плавно замедляется, а не резко останавливается.

Это часто называют lerp, сокращением от линейной интерполяции. Доля определяет характер движения: 0.1 — плавное, 0.3 — резкое, 0.02 — медленное и невесомое. Круг никогда не достигнет цели точно, но через секунду он будет ближе чем на один пиксель — этого никто не заметит.

Храни x и y как десятичные числа в отдельных переменных. Rect хранит целые числа, поэтому шаг в 0.4 пикселя округлится до 0, и движение остановится, не достигнув цели.

challenge icon

Задание

Легко

Круг прыгает к каждому щелчку. Сделай так, чтобы он скользил: замени x = target_x и y = target_y строками, которые каждый кадр перемещают x и y на одну десятую пути к цели.

Попробуйте сами

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

Все уроки раздела Звук и игровые ощущения

Потренируйтесь самостоятельно: Песочница Pygame