Клиент делает снимки, включающие положение (x,y) и скорость (x,y), а также угол и временную метку сервера, и добавляет их в буфер.
Сам клиент может запускать игру с любым кадром в секунду (80-100).
Я хотел бы создать интерполяцию моментального снимка с использованием интерполяции Эрмита, глядя на deltaTime для каждого кадра визуализируйте на стороне клиента и интерполируйте позицию немного ближе к новой позиции в буфере, пока я не получу новый пакет с сервера, но я не знаю, как решить эту проблему, чтобы получить плавную анимацию.< /p>
Вот как выглядит моя функция обновления:
Код: Выделить всё
#include "interpolation.hpp"
fsx::Interpolation::Interpolation(sf::Time& serverTime)
: m_serverTime{serverTime}
, m_position{0.f, 0.f}
, m_angle{0.f}
, m_time{0.f}
, m_alpha{0.f}
{
}
void fsx::Interpolation::setPosition(sf::Vector2f position)
{
this->m_position = fsx::Global::SFVecToB2Vec(position);
}
void fsx::Interpolation::setAngle(float angle)
{
this->m_angle = angle;
}
sf::Vector2f fsx::Interpolation::getPosition()
{
return fsx::Global::B2VecToSFVec(this->m_position);
}
float fsx::Interpolation::getAngle()
{
return this->m_angle * fsx::Global::RADTODEG;
}
void fsx::Interpolation::pushState(fsx::Interpolation::PositionData&& data)
{
this->m_serverTime = sf::seconds(data.m_serverTime);
this->m_buffer.push_back(std::move(data));
if (this->m_buffer.size() > 10)
{
this->m_buffer.pop_front();
}
this->m_time = 0.f;
}
fsx::Interpolation::PositionData fsx::Interpolation::hermite(const PositionData& older,
const PositionData& newer,
float t)
{
// Apply cubic easing to 't'
float t2 = t * t;
float t3 = t2 * t;
// Easing functions (smoothstep easing)
float a = 1 - 3 * t2 + 2 * t3;
float b = t2 * (3 - 2 * t);
float c = t * std::pow(t - 1, 2);
float d = t2 * (t - 1);
// Interpolate position using Hermite spline formula with easing
PositionData interpolated;
interpolated.m_position = a * older.m_position + b * newer.m_position + c * older.m_velocity + d * newer.m_velocity;
return interpolated;
}
inline float fsx::Interpolation::slerpRotation(float angle1, float angle2, float alpha)
{
auto angleDiff = angle2 - angle1;
angleDiff = static_cast(std::fmod(angleDiff, 2 * fsx::Global::MPI));
angleDiff =
static_cast(std::fmod(angleDiff + 3 * fsx::Global::MPI, 2 * fsx::Global::MPI) - fsx::Global::MPI);
return angle1 + alpha * angleDiff;
}
void fsx::Interpolation::update(float renderTime, float deltaTime, sf::Time& clientTime)
{
if (this->m_buffer.size() < 2)
{
this->m_position = this->m_buffer.front().m_position;
this->m_angle = this->m_buffer.front().m_angle;
// std::cout m_buffer[1];
float serverDeltaTime = newer.m_serverTime - older.m_serverTime;
this->m_alpha = this->m_time / serverDeltaTime;
this->m_position = this->hermite(older, newer, this->m_alpha).m_position;
this->m_angle = this->slerpRotation(older.m_angle, newer.m_angle, this->m_alpha);
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79175662/snapshot-interpolation-in-game[/url]
Мобильная версия