Разработка игры: Как добавить ускорение к скорости?

У меня есть представление, которое мне нужно масштабировать с ускорением, я имею в виду, что когда масштаб MIN_SCALE, скорость должна быть медленной, но когда масштаб близок к MAX_SALE, скорость должна быть более высокой. Теперь моя скорость всегда одинакова.

Существует ряд кадров, которые View будет использовать для своего движения:

numberOfFrames = Math.round((float)ANIMATION_TIME/GameLoopThread.FRAME_PERIOD);
frameCount = 0;

и я вычисляю scaleVelocity с этим количеством кадров:

scaleVelocity = (MAX_SCALE-MIN_SCALE)/numberOfFrames;

На каждой итерации игрового цикла я обновляю масштаб представления с помощью этого кода:

if (frameCount<numberOfFrames) {
    currentScale = currentScale + scaleVelocity;
    frameCount++;
}

Когда количество кадров достигнет numberOfFrames, анимация должна закончиться.

Как я могу добавить ускорение к этому коду? имейте в виду, что ускорение должно учитывать, что представление должно достичь MAX_SCALE в последнем кадре из переменной frameCount.


person NullPointerException    schedule 27.09.2019    source источник


Ответы (1)


скриншот из документов Android

Определите свой интерполятор

INTERPOLATOR = new AccelerateInterpolator();  

при вычислении scaleVelocity получить текущее интерполированное значение

float interpolatedValue = INTERPOLATOR.getInterpolation(frameCount / numberOfFrames);

getInterpolation() возвращает значение от 0 (начало анимации) до 1 (конец анимации).

scaleVelocity = (MAX_SCALE-MIN_SCALE)/numberOfFrames * interpolatedValue;  // use min,max func if needed.

математическое уравнение интерполятора ускорения: f (x) = x², если вы хотите большего изменения, создайте свой собственный интерполятор.

рабочий метод тестирования анимации.

 private void testAnim() {
    int numberOfFrames = 100;//Math.round((float)ANIMATION_TIME/GameLoopThread.FRAME_PERIOD);
    float frameCount = 0;
    float MAX_SCALE = 4;
    float MIN_SCALE = 0.1f;
    float scaleVelocity;
    float currentScale ;
    Interpolator INTERPOLATOR = new AccelerateInterpolator();

    do {
        float interpolatedValue = INTERPOLATOR.getInterpolation(frameCount / numberOfFrames);
        scaleVelocity = (MAX_SCALE - MIN_SCALE) * interpolatedValue;

        currentScale = Math.max(MIN_SCALE, scaleVelocity);
        ++frameCount;
        Log.d("STACK", "testAnim: currentScale = " + currentScale);
        // apply scale to view.
    } while (frameCount < numberOfFrames);

    // finally set final value of animation.
    currentScale = MAX_SCALE;
    // apply scale to view.

}
person Rishabh Dhawan    schedule 27.09.2019
comment
спасибо, но если я сделаю вашу логику, она даст шкалу от 0,1 до 1,4, что-то не работает, потому что мой MIN_SCALE равен 0,1, а MAX_SCALE равен 4,0 - person NullPointerException; 27.09.2019
comment
Я отредактировал свой ответ, который включает метод рабочего теста, который предоставляет значения шкалы от MIN_SCALE до MAX_SCALE. - person Rishabh Dhawan; 28.09.2019
comment
Наконец, я решаю это, используя эту формулу: currentScale = ((MAX_SCALE-MIN_SCALE)*(scaleInterpolator.getInterpolation((float)(frameCount+1)/numberOfFrames)))+MIN_SCALE; - person NullPointerException; 28.09.2019
comment
что вы думаете о моей формуле? - person NullPointerException; 28.09.2019
comment
это та же логика, за исключением того, что вы добавляете MIN_SCALE (= 0,1) к каждому кадру, вы также можете попробовать разные интерполяторы. - person Rishabh Dhawan; 28.09.2019
comment
я добавил MIN_SCALE, потому что в противном случае всегда будет 3,9 вместо 4. Правильно ли его добавить? - person NullPointerException; 28.09.2019
comment
О да, я на самом деле запустил код, и нам действительно нужно добавить MIN_SCALE вместо использования Math.max(), потому что нам нужно анимировать от MIN_SCALE до MAX_SCALE. - person Rishabh Dhawan; 28.09.2019
comment
в вашей формуле (frameCount+1) не требуется, если мы остановим цикл в (frameCount‹=numberOfFrame), это сохранит дополнительную операцию в каждом цикле - person Rishabh Dhawan; 28.09.2019