Значится так, всё происходит в двумерном пространстве, в котором, есть камера. У камеры есть текущее положение и положение, в котором она должна оказаться в итоге. Также мы знаем её предыдущее положение, отрезок времени между кадрами, можем узнать скорость на основе этих данных и т.д. Проблема: Заставить камеру плавно двигаться к цели, причём эта цель может произвольно меняться во времени - при этом камера всё равно должна двигаться по непрерывной траектории.
Нужно ли в данном вопросе использовать кривые безье и если да - то как? Я тут пробовал уже чото на основе оных кривых написать, но вышел бред, да и не хочется очередной велосипед изобретать... https://vk.com/beezoya
Немного не понял, что имеется в виду под плавностью камеры, но как вариант: (координаты камеры - точка назначения) * коэффициент ускорения
Чем выше коэффициент ускорения, тем быстрее камера окажется в нужном положении. Ну и пример движения по иксу: camera.x -= (camera.x - target.x) * .1;
В этом случае камера будет двигаться быстро, если цель находится далеко, а по мере приближения замедляться. Этот способ не оптимален, но сгодится как временное решение. А вообще такие задачи лучше всего решать через твинеры, если они есть в движке конечно.
Psycho, очень очевидное решение. Что мне в нём не нравится - чтобы камера не приближалась к цели бесконечно долго, нужно ещё прибавлять к скорости некоторую константу. Тогда через некоторое время движение по одной из координат прекратится, а по другой продолжится, будет выглядеть не очень-то красиво. А поскольку мы не хотим, чтобы при подлёте к цели камера становилась архимедленной, то такая константа будет довольно немаленькой. Кроме того, движение по диагонали на одно и то же расстояние, как если бы цель находилась на оси, будет происходить быстрее. Хочется что-нибудь поизящнее, а такой вариант, если что, всегда можно склепать за 5 минут.
ЦитатаPsycho ()
А вообще такие задачи лучше всего решать через твинеры, если они есть в движке конечно.
Движка нет, пишу на с++ (Visual Studio). А что такое твинеры? Может, я смогу вручную их реализовать?
Добавлено (08 августа 2017, 16:44) --------------------------------------------- Короче, сделал тут ещё пару попыток сделать с безье - в итоге камера описывает неописуемые пируэты и летит к точке назначения как набухавшийся вдрызг голубь.
Поэтому сделал почти как посоветовал товарищ Psycho, только приближаю не по осям отдельно, а по направлению в целом + зависимость от времени - чтоб при изменении частоты кадров скорость камеры менялась несильно.
Собсно чо вышло. Код простенький.
функцию update() вызываем на каждом кадре, параметр - отрезок времени между кадрами Factor1, Factor2 - параметры, влияют на скорость камеры
Код
#pragma once #include "Vector2.h"
class CCamera { private: vector2 mPos; vector2 mDest;
Для этого идеально в Unity подходит метод Lerp, для плаааавного передвижения объекта к заданой точке. Я в своей игре такое использую, ну очень няшно смотрится.
А если делать геморно, то делай как я на SFML ранее, а именно рассчитывал расстояние до нужной точки и с каждым приближением чуток скидывал скорость. Профит когда-то я уйду в web3
Ну так 'lerp' это по сути то же самое что я написал выше:
Да, Lerp - это обычная линейная интерполяция. Просто "программисты" на движках, где всё готово, не особо вдаются в подробности реализации. И для них, и для топикстартера ссылка. Вдруг пригодится
Добавлено (09 августа 2017, 06:04) ---------------------------------------------
Цитатаflatingo ()
Кстати, SFML это быстрая и простая обертка OpenGl, хорошо подходит для 2D среди библ. Совет автору
Автор её и использует, как я понял. И это не обертка OpenGL, а некий аналог SDL для C++
Я брал квадрат расстояния между начальной (start) и конечной (end) точкой (брал квадрат, чтобы корень не высчытывать - слишком напряжно), и потом это значение умножал на определённый методом тыка коэффицыент (mux). Это значение и являлось скоростью перемещения в зависимости от расстояния между начальной и конечной точкой пути.
А потом двигать с этой скоростью в нужном направлении - обычная нормированная разница векторов начала и конца пути помноженная на скорость. «Смерти меньше всего боятся те люди, чья жизнь имеет наибольшую ценность.» Иммануил Кант
Сообщение отредактировал Otinagi - Среда, 09 Августа 2017, 08:41
Просто вспомнил Кстати, 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/beezoya
Сообщение отредактировал puksus - Среда, 09 Августа 2017, 22:41