Алгоритм замедления вращения не работает в XNA - PullRequest
0 голосов
/ 09 февраля 2012

Я пытаюсь облегчить (постепенно переместить) вращение объекта в произвольную позицию. Угол поворота определяется классом Virtual Thumbstick, который возвращает координаты X / Y между -1 и 1. Если на джойстике нет движения, я поворачиваюсь назад к точке 0, за исключением того, что я компенсирую угол поворота изображение спрайта.

Проблема, с которой я столкнулся, состоит в том, что этот код будет позволять только приблизительно 1,5 поворота (где-то между -3 * PI и 3 * PI) вместо непрерывного вращения. Используя Math.Atan2 с координатами X / Y на ползунках, возвращаемый угол ограничен между -PI и PI, но допускает непрерывное вращение. Кроме того, если я поверну объект в одном направлении и отпущу джойстик, он будет вращаться назад в направлении, в котором он находился. Я хочу, чтобы он вращался обратно на вершину по кратчайшему маршруту.

if (VirtualThumbsticks.LeftThumbstick.Length() > .2f)
{
    double rotateTo = Math.Atan2(VirtualThumbsticks.LeftThumbstick.Y, VirtualThumbsticks.LeftThumbstick.X);

    if (rotateTo > Rotation + Math.PI) rotateTo -= (Math.PI * 2);
    if (rotateTo < Rotation - Math.PI) rotateTo += (Math.PI * 2);

    Rotation += (rotateTo - Rotation) * 0.2;
}
else
{
    Rotation += (-1.57079 - Rotation) *0.2;
}

Если есть разработчики игр на Flash / ActionScript, которые знают, о чем я говорю, пожалуйста, укажите, как я могу применить это к C #.

Спасибо всем заранее!

EDIT:

Этот кусок кода работает безупречно в AS3:

function enterFrameHandler(e:Event):void
{
    var curMouseX = Math.round(-(arrow.x - stage.mouseX));//(stage.stageWidth/2)-(stage.mouseX/2);
    var curMouseY = Math.round(-(arrow.y - stage.mouseY));//(stage.stageHeight/2)-(stage.mouseY/2);
    var angleTo:Number = Math.atan2(curMouseX, -curMouseY) * TO_DEGREES;
    if (angleTo > arrow.rotation+180) angleTo -= 360;
    if (angleTo < arrow.rotation-180) angleTo += 360;

    tf_angle.text = angleTo.toString();
    tf_mouseX.text = curMouseX.toString();
    tf_mouseY.text = curMouseY.toString();

    arrow.rotation += (angleTo - arrow.rotation) * 0.2;
}

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

Ответы [ 2 ]

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

Проблема была решена.Проблема заключалась в том, что значение вращения не было «нормализовано».По сути, если значение поворота превышает Math.PI * 2, оно должно вернуться к 0 ..., а если значение поворота упадет ниже 0, оно должно вернуться к Math.PI * 2.

Последний комментарий кэта страница решила мою проблему, и вращение теперь нормализовано.

http://forums.create.msdn.com/forums/t/27527.aspx

Мой полученный код:

if (VirtualThumbsticks.LeftThumbstick.Length() > .2f)
{
    float angleTo = (float)Math.Atan2(VirtualThumbsticks.LeftThumbstick.Y, VirtualThumbsticks.LeftThumbstick.X);

    if (angleTo > Rotation + Math.PI) angleTo -= (float)(Math.PI * 2);
    if (angleTo < Rotation - Math.PI) angleTo += (float)(Math.PI * 2);

    accelerationRotation += (angleTo - Rotation) * (float)0.25;

}
else
{
    accelerationRotation += ((float)(Math.PI / 2) - Rotation) * (float)0.2;
}

Rotation = Wrap(accelerationRotation, 0, (float)Math.PI * 2);

Функция переноса выглядит следующим образом:

public static float Wrap(float value, float lower, float upper)
{
    unchecked
    {
        if (lower >= upper)
        {
            throw new ArithmeticException("rotary bounds out of negative or zero size");
        }

        float distance = upper - lower;

        float times = (float)Math.Floor((value - lower) / distance);

        return value - (times * distance);
    }
}
0 голосов
/ 10 февраля 2012

Это написано на C # с использованием XML, поэтому параллель действий может не применяться, но я уверен, что это так. Во Flash повороты регулируются в конце каждого кадра, поскольку сохранение преобразования поворота на 123456789 градусов дает мало преимуществ. поэтому преобразование сбрасывается в значение по модулю вращения.

Однако при расчете кратчайшего поворота вы можете столкнуться с проблемами, если ожидаете некоторого большого числа и сравниваете его с каким-то другим числом вместо расчета их относительных позиций с использованием их значений по модулю.

Может быть, это источник проблемы. это просто предположение.

При странной вероятности, что вы с ней не знакомы, оператор по модулю - он же знак процента - "%" даст вам остаток от деления. это полезно для чисел, которые зацикливаются, например, для выравнивания сетки и поворотов.

Пример:

21 % 5 = 1;
 720 % 360 = 0;
...