EnterFrame твин вычисление, возвращающее неожиданный результат - PullRequest
0 голосов
/ 02 марта 2010

У меня есть следующий бит кода:

protected function onEnterFrame(e:Event):void 
{
    var diff:Number;

    // position map/tree
    if (x != _targetX) {
        diff = _targetX - x; // get the difference
        x += diff * 0.2; // tween x position
        diff = diff < 0 ? -diff : diff; // get absolute value
        if (diff < 0.05) {
            x = _targetX;
        }
    }
}

Я установил для _targetX только одно из двух значений в моем приложении: 0 или -1360. Когда я устанавливаю его на 0, анимация запускается так, как вы ожидаете. Когда я устанавливаю его на -1360, происходит странная вещь ... анимация исполняется так, как вы ожидаете, до самого последнего бита. x достигает -1359.8, а diff достигает 0.20000000000004547, и в этот момент он просто останавливается. x больше не приближается к _targetX, и эти значения просто сохраняются. Они не сдвинутся с места. В результате условное выражение if (diff < 0.05) никогда не оценивается как true, и логика анимации продолжает выполняться бесконечно.

Я предполагаю, что это как-то связано с точностью с плавающей запятой, но я не уверен в решении. Есть идеи?

1 Ответ

2 голосов
/ 02 марта 2010

Как вы говорите, это может быть проблемой из-за точности с плавающей запятой. Я просто поместил ваш код в пустой проект Flash, используя только переменные вместо позиционных свойств любого фактического объекта, и ваш код работал нормально - значение diff достигло менее 0,05, и код перестал выполняться.

Затем я попробовал с объектом на сцене, использовал его значение x и столкнулся с проблемой, которую вы описали. Кажется, что одним из простых решений является использование объекта типа Number для выполнения вычислений, а затем в конце оператора установите значение x вашего объекта равным переменной. Я вставил код, который использовал ниже, где «box» - это объект, который я положил на сцену:

addEventListener(Event.ENTER_FRAME, onEnterFrame);

var someX:Number = 0;
var _targetX:Number = -1360;

function onEnterFrame(e:Event):void 
{
    var diff:Number;

    // position map/tree
    if (someX != _targetX) 
    {
        diff = _targetX - someX; // get the difference

        someX += diff * 0.2; // tween x position
        trace("diff= ", diff, " x= ", someX);

        diff = diff < 0 ? -diff : diff; // get absolute value
        //You could equally use diff = abs(diff); here

        if (diff < 0.05) 
        {
             trace("target reached; x set to targetX");
             someX = _targetX;
        }
        box.x = someX;
    }
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...