Общий подход:
Имейте модель, поддерживающую вашу графику, и сохраняйте координаты каждого элемента в модели на модели.
- Добавьте MouseListener и реализуйте mousedown
- В вашем слушателе захватите X, Y события мыши.
- Решите, как быстро вы хотите переместить объект (постоянная скорость? Постоянное время достижения курсора? Ускорение? Замедление?)
- Напишите уравнение, которое описывает движение в направлении курсора, предпочтительно с точки зрения оставшегося расстояния, которое должно быть пройдено.Для очень быстрого подхода к замедлению это может быть дистанция, оставшаяся / 5.(например).Другие движения требуют немного геометрии / алгебры, но это ваша работа:)
- Создайте объект, который инкапсулирует вышеуказанную логику и имеет флаг, чтобы определить, когда анимация завершена.
- Использованиепоток анимации (или временная структура, как упомянуто выше, я не использовал его) для выполнения 24 или более обновлений в секунду координат X и Y модели на основе расстояния, оставшегося в Xи направление Y и вызовите repaint ().Поток должен делать это до тех пор, пока флаг завершения анимации не станет истинным, а затем прекратить вызывать repaint ().
- Затем Java будет вызывать функцию рисования для вас со скоростью, которая, как она знает, она может обработать (если вы вызываете слишкомбыстро он объединит для вас дополнительные вызовы и предотвратит блокировку программы из-за невыполнения запросов на рисование).Ваша функция рисования должна просто рисовать модель, основываясь на ее текущем состоянии, всякий раз, когда Java решит вызвать ее.
Важно, чтобы вы обновляли x и y в одном потоке, а не в независимых потоках.Это звучит как крутая идея, но она терпит неудачу, потому что планировщик потока иногда отстает от одного потока, и вы можете получить 2 или 3 обновления в одном измерении без соответствующего обновления в другом, что приведет к перемещению объекта в строке, котораяне гладко.В большинстве случаев вы должны делать все свои обновления модели (для этого и любого другого движения) в одном и том же потоке.
Обратите внимание, что ваши x & y в вашей модели, вероятно, должны быть плавающими или двойными, так как вы надеваетене хочу терять доли пикселя, особенно если движение должно быть медленным.Выражение уравнения в терминах оставшегося расстояния позволяет избежать необходимости расчета угла траектории и использования функций синуса / косинуса для выполнения обновления.Однако в некоторых случаях вам может быть легче рассчитать этот угол и использовать вместо этого синус / косинус, если вы хотите, чтобы сложное движение, которое не было легко преобразовать, было выражено через оставшееся расстояние.Делайте то, что делает ваш код понятным, оптимизируйте позже, если это необходимо.
24 обновления в секунду - это стандартная частота кадров для видеокамер, и это число является минимумом, который относится к мерцанию слияния человекаглаз, если вы обновите медленнее, чем люди будут видеть движение как рывок.Для максимальной плавности вы бы хотели более 60 раз в секунду, но это, вероятно, необходимо только для видеоигр и создает гораздо большую стоимость производительности.Выберите минимальную частоту обновления, которую вы считаете визуально удовлетворительной.
Также неплохо иметь флаг в потоке обновлений, который включает и выключает его, когда есть что обновить, чтобы он не запрашивал перерисовку ни за что.причина, когда нечего оживлять.Убедитесь, что флаг помечен ключевым словом volatile, так как он будет обновлен другими потоками.Если у вас одновременно запущено несколько анимаций, вы можете включать и выключать поток в зависимости от наличия объектов анимации в списке (их удаление по завершении)