Задать вопрос
@historydev

Как избежать размытия объекта при изменении позиции физикой?

Для отрисовки используется p5js, но это можно повторить на любом языке и любой граф. библиотеке (не движком).

Если двигать объект без фикс. временного шага и интерполяции - он чёткий, а с фикс. и интерполяцией - мыльный, если убрать интерполяцию - ещё и дёрганый по понятным причинам.
- Комменты оставил.

Песочница: editor.p5js.org, вставьте пример слева и запустите кнопкой или ctrl + enter.
const step = 1 / 60; // Шаг физики
let acc = 0; // Аккумулятор

let pos1; // Верхний прямоугольник 
let lastPos1; // Последняя позиция верхнего прямоугольника
let pos2; // Нижний прямоугольник

// Функция вызывается один раз (init)
function setup() {
  createCanvas(windowWidth, windowHeight); // Создаём канвас
  frameRate(144); // Устанавливаем кол-во кадров / сек
  
  // Инициализируем позиции прямоугольников
  pos1 = createVector(0, height/2 - 100); 
  pos2 = createVector(0, height/2);
}

// Функция вызывается каждый кадр
function draw() {
  background(220); // Заливаем фон
  
  acc += deltaTime / 1000; // Увеличиваем аккумулятор
  
  lastPos1 = pos1; // Сохраняем последнюю позицию верхнего прямоугольника
  
  
  while(acc >= step) { // Пока аккумулятор больше шага физики
    pos1.x += 100 * step; // Двигаем верхний прямоугольник вправо
    acc -= step; // Уменьшаем аккумулятор
  }
  
  pos2.x += 100 * (deltaTime / 1000); // Двигаем нижний прямоугольник вправо
  
  const alpha = acc / step; // Коэффициент интерполяции
  
  // Интерполяция позиции
  const interpPos = p5.Vector.lerp(lastPos1, pos1, alpha);
  
  // Верхний прямоугольник (двигает: физики)
  rect(interpPos.x, interpPos.y, 200, 50);
  
  // Нижний прямоугольник (двигает: рендер)
  rect(pos2.x, pos2.y, 200, 50);
}
  • Вопрос задан
  • 116 просмотров
Подписаться 1 Простой 12 комментариев
Помогут разобраться в теме Все курсы
  • Нетология
    Разработчик игр на Unity
    13 месяцев
    Далее
  • Skillbox
    Профессия Разработчик игр
    12 месяцев
    Далее
  • Академия Эдюсон
    Разработчик игр на Unity: тариф PRO
    6 месяцев
    Далее
Решения вопроса 1
opium
@opium
Просто люблю качественно работать
У тебя lastPos1 = pos1 копирует ссылку на вектор, а не его значение. После физического цикла оба имени указывают на один объект с уже обновлённым x, и lerp интерполирует между двумя одинаковыми точками — по факту ничего не делает. Замени на lastPos1 = pos1.copy(), тогда интерполяция заработает как задумано. Если после этого останется мыльность от субпиксельного рендера — попробуй округлить координаты перед отрисовкой, но для плавной анимации это может добавить лёгкое дрожание.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы