Спрайт следует другим гибким путем в определенных пределах расстояния - PullRequest
1 голос
/ 04 февраля 2020

Я пытаюсь заставить спрайт следовать за другим гибким способом.

Если основной спрайт движется быстрее, последователь отстает, а если более медленный - ближе.

Само движение работает с следующий (псевдо) код:

target_vector = Vector2D(mainsprite_x, mainsprite_y)
follower_vector = Vector2D(follower_x, follower_y)

new_follower_vector = Vector2D.lerp(follower_vector, target_vector, LERP_FACTOR)

В настоящее время я использую различные константы для LERP_FACTOR, который работает "okayi sh".

Теперь я хотел бы добавить ограничения, как много может быть позади последователя и насколько близко он может стать.

Я использую Pygame, но это не должно иметь значения.

Как мне этого добиться?

1 Ответ

0 голосов
/ 05 февраля 2020

Я рекомендую рассчитать расстояние между ведомым и спрайтом и вектором направления устройства от (follower_x, follower_y) до (mainsprite_x, mainsprite_y).
Расстояние можно получить вычисляя евклидово расстояние . Pygame предоставляет distance_to() для этого. Вектор единицы измерения Th может быть вычислен путем деления вектора направления на расстояние или путем нормализации (normalize()) вектора направления:

target_vector = Vector2(mainsprite_x, mainsprite_y)
follower_vector = Vector2(follower_x, follower_y)

distance = follower_vector.distance_to(target_vector)
direction_vector = target_vector - follower_vector
if distance > 0:
    direction_vector /= distance

Теперь вы можете определить точное значение step_distance и перейдите к следующему направлению спрайта:

if distance > 0:
    new_follower_vector = follower_vector + direction_vector * step_distance.

Определите maximum_distance и minimum_distance. Минимальное расстояние шага:

min_step = max(0, distance - maximum_distance)

Максимальное расстояние шага

max_step = distance - minimum_distance

Соберите все вместе:

minimum_distance    = ???
maximum_distance    = ???
target_vector       = Vector2(mainsprite_x, mainsprite_y)
follower_vector     = Vector2(follower_x, follower_y)
new_follower_vector = Vector2(follower_x, follower_y)

distance = follower_vector.distance_to(target_vector)
if distance > minimum_distance:
    direction_vector    = (target_vector - follower_vector) / distance
    min_step            = max(0, distance - maximum_distance)
    max_step            = distance - minimum_distance
    step_distance       = min_step + (max_step - min_step) * LERP_FACTOR
    new_follower_vector = follower_vector + direction_vector * step_distance

См. Пример:

import pygame

LERP_FACTOR      = 0.05
minimum_distance = 25
maximum_distance = 100

def FollowMe(pops, fpos):
    target_vector       = pygame.math.Vector2(*pops)
    follower_vector     = pygame.math.Vector2(*fpos)
    new_follower_vector = pygame.math.Vector2(*fpos)

    distance = follower_vector.distance_to(target_vector)
    if distance > minimum_distance:
        direction_vector    = (target_vector - follower_vector) / distance
        min_step            = max(0, distance - maximum_distance)
        max_step            = distance - minimum_distance
        step_distance       = min_step + (max_step - min_step) * LERP_FACTOR
        new_follower_vector = follower_vector + direction_vector * step_distance

    return (new_follower_vector.x, new_follower_vector.y) 

pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

follower = (100, 100)
run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    player   = pygame.mouse.get_pos()
    follower = FollowMe(player, follower)

    window.fill(0)  
    pygame.draw.circle(window, (0, 0, 255), player, 10)
    pygame.draw.circle(window, (255, 0, 0), (round(follower[0]), round(follower[1])), 10)
    pygame.display.flip()
...