Сброс вращения модели при остановке ввода - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть модель, представляющая корабль игрока, постепенно наклоняющийся, когда игрок стреляет.Например, вот код, который наклоняет корабль вправо:

В Update() класса Игры:

if (ship.rightTurnProgress < 1 && (currentKeyState.IsKeyDown(Keys.D)))
{
    ship.rightTurnProgress += (float)gameTime.ElapsedGameTime.TotalSeconds * 30;
}

В Update() класса корабля:

if (currentKeyState.IsKeyDown(Keys.D))
{
   Velocity += Vector3.Right * VelocityScale * 10.0f;
   RotationMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * 
     Matrix.CreateRotationY(0.4f * rightTurnProgress);
}

Это то, что я пытаюсь сделать, чтобы освободиться от наклона, когда он прекращает обстрел:

В Update() класса Игры:

if (ship.rightTurnProgress > 0 && currentKeyState.IsKeyUp(Keys.D))
{
    ship.rightTurnProgress -= (float)gameTime.ElapsedGameTime.TotalSeconds * 30;
}

В Update() класса Корабль:

if (currentKeyState.IsKeyUp(Keys.D) && rightTurnProgress > 0)
{
    RotationMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) *
      Matrix.CreateRotationY(-0.4f * rightTurnProgress);
}

Поскольку облегчение бедного работает без проблем, я думал, что выход из бедного будет простым делом, направленным на изменение процесса.Тем не менее, он имеет тенденцию не возвращаться к позиции по умолчанию после долгого перерыва.Если вы нажмете клавишу, она полностью вернется к полному наклону в противоположном направлении.Это совсем не то, что я ожидал.Что мне здесь не хватает?

Ответы [ 3 ]

1 голос
/ 23 февраля 2012

Я предлагаю вам представить вращение вашего корабля как кватернион.Таким образом, вы можете использовать функцию интерполяции, такую ​​как slerp .Просто возьмите второй кватернион, представляющий целевой угол наклона, и корабль будет плавно вращаться, пока не достигнет заданного угла.

Вот хороший урок по кватернионам .Если вы хотите избежать кватернионов, используйте MathHelper.Lerp для плавного перехода от текущего значения к цели.

if (currentKeyState.IsKeyDown(Keys.D))
{
    ship.TurnProgress = MathHelper.Lerp(ship.TurnProgress, 1, somefloat * timeDelta);
}
else if (currentKeyState.IsKeyDown(Keys.a))
{
    ship.TurnProgress = MathHelper.Lerp(ship.TurnProgress, -1, somefloat * timeDelta);
}
else  (currentKeyState.IsKeyDown(Keys.D))
{
    ship.TurnProgress = MathHelper.Lerp(ship.TurnProgress, 0, somefloat * timeDelta);
}

Редактировать: Также имеется переполнение стека GameDev, поэтому проверьте его, если у вас есть дополнительные вопросы.

0 голосов
/ 22 февраля 2012

Вы создаете «абсолютную» матрицу вращения, поэтому вам не нужно переворачивать знак на -0.4f. Почему бы просто не иметь переменную с именем ship.lean и вычислять матрицу вращения при каждом обновлении. Тогда вам просто нужна логика, чтобы ослабить ship.lean между -1 (наклон влево) и 1 (наклон вправо) или 0 для отсутствия наклонов.

0 голосов
/ 22 февраля 2012

Если вы не знаете, сколько длится ход или у вас есть какой-то вектор ускорения, вам придется подождать, пока поворот не остановится, прежде чем вернуть угол спрайта в нейтральное положение, а затем то, что происходит, когда игрок поворачивает налево, прежде чем спрайт достигнет нейтральная позиция? Я предполагаю, что когда вы поворачиваете направо с помощью RightTurnProgress, у вас также есть LeftTurnProgress, я предлагаю вам объединить их в одну переменную, чтобы сохранить плавность и избежать эффекта привязки, который вы получаете.

...