Как именно работает анимация в java?

Я не совсем уверен, как именно люди создают анимацию в java, например, переводя квадрат на экран. Когда я пытаюсь изменить положение прямоугольника с помощью цикла for, все выполняется мгновенно, и я получаю конечную координату прямоугольника. Итак, что я хочу знать, так это то, как люди достигают этой плавной анимации сверхурочно, и если я хочу создать свой собственный класс анимации по какой-либо причине, как мне добавить задержку, чтобы она отображалась как анимация вместо мгновенного изменения позиции в java?


person AnotherRandomUser    schedule 13.05.2016    source источник
comment
В двух словах: запуск чего-то вроде rectangle.x = (System.currentTimeInMillis() - startTimeInMillis) * 0.5 + 10; каждые несколько миллисекунд. Или просто запускать rectangle.x += 2; каждые несколько миллисекунд.   -  person user253751    schedule 13.05.2016
comment
Эй, спасибо. как бы я делал прямоугольник.x каждую миллисекунду, не заставляя поток спать или нарушая выполнение другого события?   -  person AnotherRandomUser    schedule 13.05.2016
comment
Вы должны иметь представление о параллелизме. По сути, у вас есть поток/таймер, который тикает в фоновом режиме, который отправляет уведомления наблюдателям, которые обновляют свои состояния в соответствии с их требованиями, а затем выводятся на экран (в отдельном потоке, часто известном как поток диспетчеризации событий). Метод, с помощью которого вы в конечном итоге достигнете этого, будет зависеть от используемой вами структуры.   -  person MadProgrammer    schedule 13.05.2016
comment
Для примера пример, пример. Анимация — сложный пример (например) и по моему опыту для этих задач лучше использовать выделенные библиотеки   -  person MadProgrammer    schedule 13.05.2016
comment
Вау, кажется, теперь я понял. Итак, чтобы сделать подобную анимацию и по-прежнему слушать пользователя, мне нужен другой поток, верно? Но разве это не удобно? Что, если у меня есть несколько анимаций, которые мне нужно запустить, но поток не может запустить их все, потому что время анимации разное? Означает ли это, что мне нужно использовать еще больше потоков для этих нескольких анимаций?   -  person AnotherRandomUser    schedule 13.05.2016
comment
@AnotherRandomUser Что делать, если у меня есть несколько анимаций, которые мне нужно запустить, но поток не может запустить их все, потому что синхронизация анимации отличается? — это когда вы должны использовать один поток, который генерирует тики с постоянной скоростью все ваши анимации будут отслеживать это и вносить соответствующие изменения в зависимости от их потребностей. Вот как работает что-то вроде TimingFramework   -  person MadProgrammer    schedule 13.05.2016
comment
@AnotherRandomUser Мне нужен другой поток, верно? Но разве это не удобно? — Вы обнаружите, что почти все фреймворки с графическим интерфейсом работают по этому простому принципу: один поток для управления всеми событиями, происходящими в пользовательском интерфейсе, на самом деле это область научных исследований. (чтобы создать потокобезопасную структуру, которую действительно можно использовать). Существует ряд фреймворков и подходов, которые могут помочь, в зависимости от того, какой фреймворк вы используете.   -  person MadProgrammer    schedule 13.05.2016
comment
Посмотрите на JavaFX и переходы.   -  person ManoDestra    schedule 13.05.2016


Ответы (2)


Вы можете просто сохранить координаты x и y прямоугольника. Затем запустите цикл while, в котором вы проверяете, прошло ли заданное количество времени. Если это так, увеличьте переменные положения.

Код (потребуются незначительные корректировки для удовлетворения ваших потребностей):

int tick = 500; //set this to whatever you want
long lastTime = System.currentTimeInMillis();
while(true) {
 long currTime = System.currentTimeInMillis();
 if (currTime > lastTime + tick) {
  lastTime = currTime;
  x = x + 1; //replace this with your object's position
 }
}
person nhouser9    schedule 13.05.2016
comment
Эй, спасибо за работу, но у меня есть быстрый вопрос. Эта штука запускается в отдельном потоке, верно? Что, если я хочу сделать 10 разных анимаций, нужно ли мне 10 потоков, чтобы это работало, и как мне это сделать, когда на моем компьютере их всего 8? Я просто хочу протестировать. - person AnotherRandomUser; 13.05.2016
comment
Во-первых, вы все еще можете создать 10 потоков на машине с 8 ядрами. Компьютер абстрагирует его и будет запускать потоки на одном ядре параллельно. Во-вторых, вам НЕ НУЖНО запускать это в отдельном потоке, но это хорошая идея. - person nhouser9; 13.05.2016
comment
Просто имейте в виду, что в зависимости от фреймворка вы можете рискнуть условиями гонки между тикером и средством визуализации (или, если вы работаете в потоке событий, предотвратить дальнейшее взаимодействие с пользовательским интерфейсом). - person MadProgrammer; 13.05.2016
comment
@AnotherRandomUser Используйте один поток, который генерирует тики в постоянном состоянии, позвольте всем другим анимациям наблюдать за этим и вносить соответствующие изменения, так работает TimingFramework. - person MadProgrammer; 13.05.2016

Вы можете добавить задержку, используя метод Thread.sleep(long millis), который остановит выполнение текущего потока на указанное количество миллисекунд. Однако, вероятно, есть лучший способ.

person Pyrrhic    schedule 13.05.2016
comment
Эй, спасибо за ответ, но я не уверен, что thread.sleep — лучший вариант, потому что, скажем, вы создаете меню, верно? Что, если вы скажете потоку заснуть для какой-то анимации, но как тогда он отреагирует на щелчок пользователя, если он заснет? - person AnotherRandomUser; 13.05.2016
comment
Я не верю, что он сможет зарегистрировать щелчок пользователя, пока он спит. - person Pyrrhic; 13.05.2016
comment
Я думаю да. Я пытался найти в Google, как это будет сделано, но пока ничего не нашел, и я искал более часа, прежде чем прийти сюда и задать вопрос. - person AnotherRandomUser; 13.05.2016
comment
@DogeOverlord Это предполагает многое, если вы вызываете Thread.sleep в основном потоке фреймворка или потоке событий, тогда да, это приведет к тому, что пользовательский интерфейс перестанет отвечать - person MadProgrammer; 13.05.2016