Beanish - это правильно, вы должны умножить на GameTime, если хотите плавности. Физика - это перебор, если вы хотите, чтобы ваша анимация выглядела гладко.
Лучший способ, который я нашел для анимации, - это использовать интерполяцию положения, , чтобы это работало, вы должны знать начальную (вы уже знаете) и конечную позицию изображения.
Если вы хотите перейти от A к B, скажем, за 2 секунды, вы можете использовать следующий код.
Vector2 a = new Vector2(0, 0);
Vector2 b = new Vector2(0, 100);
float elapsedTime = 0;
float duration = 2.0;
public override void Update(GameTime gameTime)
{
float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
elapsedTime += dt;
if (elapsedTime > 1)
elapsedTime = 1;
float param = elapsedTime / duration;
pos = Vector2.Lerp(a, b, param);
}
Самое лучшее в использовании этого подхода - это то, что теперь вы можете использовать "замедление", чтобы анимация выглядела действительно очень красиво.
Для этого просто добавьте операцию Power в параметр интерполятора:
pos = Vector2.Lerp(a, b, (float)Math.Pow(param /2.0, 0.5));
Это замедлит изображение по мере приближения к B. Вы можете поиграть со значением экспоненты (0.5), чтобы получить другие результаты, например, 2.0.
Другая важная вещь заключается в том, что ваше изображение всегда будет останавливаться на B. Если вы используете интеграционный подход Эйлера (ваш подход, добавляя скорость в каждом кадре), у вас могут возникнуть проблемы с остановкой изображения в правильном положении (иначе B) и становится еще хуже при использовании 2 или 3 измерений.
Чтобы узнать больше об ослаблении, отметьте Уравнения ослабления Роберта Пеннера .