Среда, 15 Августа 2018, 02:18

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » Общие обсуждения программистов » Плавное движение камеры
Плавное движение камеры
puksusДата: Вторник, 08 Августа 2017, 03:21 | Сообщение # 1
участник
Сейчас нет на сайте
Значится так, всё происходит в двумерном пространстве, в котором, есть камера.
У камеры есть текущее положение и положение, в котором она должна оказаться в итоге. Также мы знаем её предыдущее положение, отрезок времени между кадрами, можем узнать скорость на основе этих данных и т.д.
Проблема: Заставить камеру плавно двигаться к цели, причём эта цель может произвольно меняться во времени - при этом камера всё равно должна двигаться по непрерывной траектории.

Нужно ли в данном вопросе использовать кривые безье и если да - то как?
Я тут пробовал уже чото на основе оных кривых написать, но вышел бред, да и не хочется очередной велосипед изобретать...


https://vk.com/puksus
PsychoДата: Вторник, 08 Августа 2017, 05:16 | Сообщение # 2
Психоламер
Сейчас нет на сайте
Немного не понял, что имеется в виду под плавностью камеры, но как вариант:
(координаты камеры - точка назначения) * коэффициент ускорения

Чем выше коэффициент ускорения, тем быстрее камера окажется в нужном положении. Ну и пример движения по иксу:
camera.x -= (camera.x - target.x) * .1;

В этом случае камера будет двигаться быстро, если цель находится далеко, а по мере приближения замедляться. Этот способ не оптимален, но сгодится как временное решение. А вообще такие задачи лучше всего решать через твинеры, если они есть в движке конечно.
puksusДата: Вторник, 08 Августа 2017, 16:44 | Сообщение # 3
участник
Сейчас нет на сайте
Psycho, очень очевидное решение. Что мне в нём не нравится - чтобы камера не приближалась к цели бесконечно долго, нужно ещё прибавлять к скорости некоторую константу. Тогда через некоторое время движение по одной из координат прекратится, а по другой продолжится, будет выглядеть не очень-то красиво. А поскольку мы не хотим, чтобы при подлёте к цели камера становилась архимедленной, то такая константа будет довольно немаленькой. Кроме того, движение по диагонали на одно и то же расстояние, как если бы цель находилась на оси, будет происходить быстрее.
Хочется что-нибудь поизящнее, а такой вариант, если что, всегда можно склепать за 5 минут.

Цитата Psycho ()
А вообще такие задачи лучше всего решать через твинеры, если они есть в движке конечно.

Движка нет, пишу на с++ (Visual Studio). А что такое твинеры? Может, я смогу вручную их реализовать?

Добавлено (08 августа 2017, 16:44)
---------------------------------------------
Короче, сделал тут ещё пару попыток сделать с безье - в итоге камера описывает неописуемые пируэты и летит к точке назначения как набухавшийся вдрызг голубь.

Поэтому сделал почти как посоветовал товарищ Psycho, только приближаю не по осям отдельно, а по направлению в целом + зависимость от времени - чтоб при изменении частоты кадров скорость камеры менялась несильно.

Собсно чо вышло. Код простенький.


на сломанные отступы внимания не обращаем


ну и на всякий случай


https://vk.com/puksus

Сообщение отредактировал puksus - Вторник, 08 Августа 2017, 16:48
PsychoДата: Вторник, 08 Августа 2017, 18:08 | Сообщение # 4
Психоламер
Сейчас нет на сайте
Цитата puksus ()
приближаю не по осям отдельно

Я привел пример перемещения по одной оси, писать таким образом перемещение по двум осям не айс.
Цитата puksus ()
А что такое твинеры? Может, я смогу вручную их реализовать?

Это вспомогательные классы для программной анимации. Реализовать вручную не так уж сложно, можешь глянуть примеры на GitHub (клац!).
flatingoДата: Среда, 09 Августа 2017, 00:37 | Сообщение # 5
участник
Сейчас нет на сайте
Для этого идеально в Unity подходит метод Lerp, для плаааавного передвижения объекта к заданой точке. Я в своей игре такое использую, ну очень няшно смотрится.

Код примерно такой:
Код
transform.position = Vector3.Lerp(start.position, end.position, Time.time);


А если делать геморно, то делай как я на SFML ранее, а именно рассчитывал расстояние до нужной точки и с каждым приближением чуток скидывал скорость. Профит



PsychoДата: Среда, 09 Августа 2017, 00:45 | Сообщение # 6
Психоламер
Сейчас нет на сайте
Цитата flatingo ()
Для этого идеально в Unity

Цитата puksus ()
Движка нет, пишу на с++ (Visual Studio)

WTF?
flatingoДата: Среда, 09 Августа 2017, 00:49 | Сообщение # 7
участник
Сейчас нет на сайте
Цитата Psycho ()
WTF?


Просто вспомнил

Кстати, SFML это быстрая и простая обертка OpenGl, хорошо подходит для 2D среди библ. Совет автору



PsychoДата: Среда, 09 Августа 2017, 01:01 | Сообщение # 8
Психоламер
Сейчас нет на сайте
Цитата flatingo ()
Просто вспомнил

Ну так 'lerp' это по сути то же самое что я написал выше:

start.position + ( end.position - start.position ) * elapsed.time;

С Unity никогда не работал, так что поправь если ошибаюсь.


Сообщение отредактировал Psycho - Среда, 09 Августа 2017, 01:01
VuvkДата: Среда, 09 Августа 2017, 06:04 | Сообщение # 9
заслуженный участник
Сейчас нет на сайте
Цитата Psycho ()
Ну так 'lerp' это по сути то же самое что я написал выше:

Да, Lerp - это обычная линейная интерполяция. Просто "программисты" на движках, где всё готово, не особо вдаются в подробности реализации. И для них, и для топикстартера ссылка. Вдруг пригодится

Добавлено (09 августа 2017, 06:04)
---------------------------------------------

Цитата flatingo ()
Кстати, SFML это быстрая и простая обертка OpenGl, хорошо подходит для 2D среди библ. Совет автору

Автор её и использует, как я понял. И это не обертка OpenGL, а некий аналог SDL для C++


Мой блог
Мой канал на Youtube
Lokemundux Desco Domus Shaantitus. Caecux Vorox Acerbus-shatruex! Crudux Cruo!
OtinagiДата: Среда, 09 Августа 2017, 08:39 | Сообщение # 10
постоянный участник
Сейчас нет на сайте
Я брал квадрат расстояния между начальной (start) и конечной (end) точкой (брал квадрат, чтобы корень не высчытывать - слишком напряжно), и потом это значение умножал на определённый методом тыка коэффицыент (mux). Это значение и являлось скоростью перемещения в зависимости от расстояния между начальной и конечной точкой пути.

speed = ((end.x - start.x)^2 + (end.y - start.y)^2) * mux;

А потом двигать с этой скоростью в нужном направлении - обычная нормированная разница векторов начала и конца пути помноженная на скорость.


«Смерти меньше всего боятся те люди, чья жизнь имеет наибольшую ценность.»
Иммануил Кант


Сообщение отредактировал Otinagi - Среда, 09 Августа 2017, 08:41
flatingoДата: Среда, 09 Августа 2017, 10:48 | Сообщение # 11
участник
Сейчас нет на сайте
Цитата Vuvk ()
И это не обертка OpenGL, а некий аналог SDL для C++


"Это не обед, а вкусная и здоровая пища". Звучит как-то так и очевидно.

Цитата Otinagi ()
Да, Lerp - это обычная линейная интерполяция. Просто "программисты" на движках, где всё готово, не особо вдаются в подробности реализации.


Это ты типа меня так обосрал сейчас, не зная человека? Забавно



VuvkДата: Среда, 09 Августа 2017, 11:39 | Сообщение # 12
заслуженный участник
Сейчас нет на сайте


Мой блог
Мой канал на Youtube
Lokemundux Desco Domus Shaantitus. Caecux Vorox Acerbus-shatruex! Crudux Cruo!
puksusДата: Среда, 09 Августа 2017, 22:33 | Сообщение # 13
участник
Сейчас нет на сайте
Цитата flatingo ()
Просто вспомнил
Кстати, SFML это быстрая и простая обертка OpenGl, хорошо подходит для 2D среди библ. Совет автору

На нём и делаю. Если вдруг возможностей не хватает - пилю простенькие шейдеры. Когда-нибудь, быть может, пересяду на чистый OpenGL, но пока что возможностей хватает. Кроме того, на него повесил также и звук и клаву с мышью.

Цитата flatingo ()
А если делать геморно, то делай как я на SFML ранее, а именно рассчитывал расстояние до нужной точки и с каждым приближением чуток скидывал скорость. Профит

Пока что примерно так и есть. Может быть, когда-нибудь решусь усложнить
double dist = (mDest - mPos).length();
double speed = dist * mFactor2 + mFactor1;
потом прибавляю вектор равный по длине спиду помноженный на отрезок времени между фреймами, ну и с проверкой на то чтоб не продвинулся дальше положенного.

Цитата Otinagi ()
брал квадрат, чтобы корень не высчытывать - слишком напряжно

Камера двигается 1 раз за кадр, так что тут производительность не важна. Тут это не для каждого из 10к объектов на сцене высчитывать расстояние. Я кстати в прошлых проектах угол хранил в виде косинуса и синуса - чтобы не пересчитывать эти значения каждый кадр. Но убрал, потому что больше гемора, а производительности и так с головой хватает. Кроме того, sfml при рисовке всё равно принимает угол в градусах - а значит, "внутри" всё равно будет пересчитывать.

Цитата Vuvk ()
В OpenGL есть управление окнами? Ввод/вывод? Звук? Или даже сеть? А в SFML есть.

Это да, поэтому это скорее аналог DirectX, в котором всё это есть, но который намного тяжелее(и в плане понимания и в плане количества кода), только sfml ещё и кроссплатформенная штукенция.


https://vk.com/puksus

Сообщение отредактировал puksus - Среда, 09 Августа 2017, 22:41
Форум игроделов » Программирование » Общие обсуждения программистов » Плавное движение камеры
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2018 Рейтинг