powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Блокировка запуска анимации до её окончания
21 сообщений из 21, страница 1 из 1
Блокировка запуска анимации до её окончания
    #37557773
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня по нажатию на кнопку запускается анимация. Как сделать, чтобы при зажатии этой кнопки анимацию на запускалась много раз очень быстро, а проигрывалась только один раз? При этом по окончании анимации, если кнопка по-прежнему зажата, то анимация должна запуститься снова.

Вобщем при зажатии кнопки должен быть эффект, как будто анимация зациклена, хотя при этом в свойствах анимации я специально зацикленность убрал.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37558705
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверх.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37558824
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

у анимации есть событие, "закончилась", вот в ней меняй флаг.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37559420
xpoft2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
триггер на IsMouseOver = false, IsPressed = true и сделай зацикленную. В твоем сценарии подвохов не вижу нигде.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37562808
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xpoft2010триггер на IsMouseOver = false, IsPressed = true и сделай зацикленную. В твоем сценарии подвохов не вижу нигде.
Уточню: по нажатии кнопки (т. е. нажал и отпустил) анимация должна один раз полностью проиграть. По зажатии (нажал и держишь) - должна быть зацикленной, при этом каждый цикл должен запускаться только один раз - анимация не должна перекрывать сама себя (а она это делает, если её на событие простого нажатия кнопки повесить).

Пример с печатанием текста. Как сделано обычно: нажал раз - одна буква, держишь кнопку - автоматом серия букв. Как мне надо: нажал раз - одна буква, держишь кнопку - одна анимация отрисовки буквы, потом друга, потом третья и т. д., а не одновременно серия анимаций отрисовки сразу кучи одинаковых букв.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37562810
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xpoft2010IsMouseOver
Мне всё же на баттоны надо.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37563841
Руки-крюки
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

Я бы посоветовал освоить VisualStateManger
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37564553
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руки-крюкиuser7320,

Я бы посоветовал освоить VisualStateManger
На баттоны клавиатуры.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37564558
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руки-крюкиuser7320,

Я бы посоветовал освоить VisualStateManger
Анимация запускается не для чего-нибудь, а для камеры в трёхмерном пространстве. А точнее, я запускаю DoubleAnimation для нужной координаты положения камеры. VisualState тут, я думаю, не нужен.

Я специально более общий вопрос задал, чтобы не конкретизировать. Нужно просто реализовать описанное выше поведение:

нажал кнопку - анимация один раз; зажал кнопку - анимация один раз, потом ещё раз и т. д. последовательно, пока зажата кнопка, а не параллельно куча одних и тех же анимаций.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37564738
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

слушай, ты что правда не можешь сообразить?

сделай простую очередь. туда пихай все клавиши.
сделай поток в программе, который будет управлять анимацией. этот потом будет смотреть на какие нито переменные UI потока.
может тебе просто поспать надо, чтобы голова трезвая была?
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37564932
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexeiKuser7320,

слушай, ты что правда не можешь сообразить?

сделай простую очередь. туда пихай все клавиши.
сделай поток в программе, который будет управлять анимацией. этот потом будет смотреть на какие нито переменные UI потока.
может тебе просто поспать надо, чтобы голова трезвая была?
Я могу придумать какой-нибудь костыль. Но я хочу узнать, есть ли какой способ сделать это по уму. "По уму" - значит просто и красиво. Вроде, задача-то тривиальная - должно быть какое-то простое решение. Ну, раз вы не знаете, значит, не тривиальная. Тогда костыль придётся.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37565087
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

ты думал, что есть уже какой то компонент в студии, который реализовывает эту логику?
ну это ж не логично так думать.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37565375
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexeiKuser7320,

ты думал, что есть уже какой то компонент в студии, который реализовывает эту логику?
ну это ж не логично так думать.
Нет, я думал, что раз задача тривиальная и распространённая (а почему бы ей не быть такой?), то народ уже давно напридумывал шаблонных решений. Я очень удивлён, что не напридумывал.

У меня камера (т. е. сам персонаж) двигается по клеточкам в трёхмерном мире. Т. е. за одно нажатие кнопки проходится одна клетка. Это я делаю, анимируя координату камеры. Когда пользователь хочет просто долго идти вперёд, то он не должен жать много раз на кнопку "вперёд", а должен просто зажать её. Так вот, у меня сейчас анимация отрабатывает по событию ButtonDown. При зажатии кнопки эти события очень быстро возникают, и анимация тоже стартует много раз, и неизбежно накладывается друг на друга. В результате камера перемещается вперёд очень быстро - с суммой скоростей всех анимаций.

Теперь понимаете, чего я хочу? )

Первое, что пришло в голову - в событии ButtonDown запустить анимацию и тут же отписаться от события ButtonDown. По окончании анимации подписаться на это же событие. Вот так и заблокирую повторные нажатия до окончания анимации. Костыль? - Костыль и кривовато придумано. Некрасиво. Да ещё непонятно, сколько попутных костылей придётся придумать, чтобы описанное реализовать.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37565563
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

ну вот , а че раньше то, не говорилось по-русски? писал какие то зажеванные мысли.

смотри:
делаешь переменную: направление движения.
на событие keydown , делаешь:
проверяем, нужно ли менять направление
если да, то меняем
если нет, то игнор нажатия.

двигать же камеру должен какой то таймер или поток.
вот ты собственно и должен управлять только направлением движения.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37565683
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexeiKuser7320,

ну вот , а че раньше то, не говорилось по-русски? писал какие то зажеванные мысли.

смотри:
делаешь переменную: направление движения.
на событие keydown , делаешь:
проверяем, нужно ли менять направление
если да, то меняем
если нет, то игнор нажатия.

двигать же камеру должен какой то таймер или поток.
вот ты собственно и должен управлять только направлением движения.
Насчёт таймера или потока - это не нужно в отдельном потоке, так как там всё проще - интерфейс не работает, пока анимация движения на одну клетку не закончилась. (Так нужно - я копирую интерфейс одной игры. Всё в порядке, это не мешает играть, а наоборот удобно.) Так что всё в потоке интерфейса можно сделать.

Далее, про направление движения. У меня тоже всё проще: клавиши клавиатуры "ввехр" и "вниз" - это вперёд и назад. Клавиши "вправо" и "влево" - повороты на месте направо и налево. Т. е. определять, куда меняется направление не нужно - за каждой клавишей своя готовая анимация закреплена. Всё на ButtonDown'ах.

Я могу ходить по клеточкам - нажимая по разу на одну клеточку. Могу зажать, но тогда либо очень быстро двигаюсь вперёд-назад, либо очень быстро поворачиваюсь. Надо только вот эту быстроту убрать.

С учётом всего этого рекомендации не изменились?


Вот вы сказали про игнор ражатия - это про Handled-свойство? Тогда у меня такой вариант, чтобы не отписываться-подписываться на события постоянно: заводить глобальную переменную, означающую, завершилась ли анимация движения, и в обработчике нажатия кнопки проверять её значение - если не завершилась, то Handled == true. Глобальную переменную менять в обработчике события завершения анимации движения. Итого для четырёх моих движений - четыре анимации и четыре глобальных переменных соответственно.

Вот только с глобальными мне не нравится - костыль.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37566344
Руки-крюки
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут вообще никакая анимация не нужна, и уж тем более VisualStateManager.

По зажатию клавишы запускаешь таймер. По отжатию останавливаешь.
Пускай таймер тикает с частатой 100 мс.
1-й тик - 1 раз двигаем персонажа.
2-20 тики - таймер делает return в начале обработчика.
20 и дальше тики - двигаем на одну клетку.

Зачем мудрить?
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37566346
Руки-крюки
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и конечно в функции передвижения сделать проверку работает ли анимация. Если работает то сделать отложенный вызов следующего передвижения (если конечно такой вызов не был уже сделан).
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37566619
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руки-крюкиТут вообще никакая анимация не нужна, и уж тем более VisualStateManager.

По зажатию клавишы запускаешь таймер. По отжатию останавливаешь.
Пускай таймер тикает с частатой 100 мс.
1-й тик - 1 раз двигаем персонажа.
2-20 тики - таймер делает return в начале обработчика.
20 и дальше тики - двигаем на одну клетку.

Зачем мудрить?
Анимация как раз нужна. По-вашему выйдет, что каждое движение персонажа будет рывками и вообще ограничено 10 кадрами в секунду. Более того, заботу о частоте кадров тут я беру на себя. В модели анимации WPF всё делает за меня сам WPF. Тем более, что в WPF нет таймеров в таком свободном доступе, как в формах. Мне приходилось импортировать компонент таймер из форм, т. к. больше никаких свободно доступных таймеров в WPF нету. Те таймеры, что отвечают за анимацию WPF - до них не добраться. Тем более непонятно, как их использовать отдельно от анимации.

Кроме того, у меня персонаж может двигаться только по клеточкам (специально), и поэтому, даже если игрок отпустил клавишу на границах между клетками, анимация движения в клетку назначения должна доиграть о конца, чтобы игрок встал на середину клетки. А у вас получается, что он может остановиться в любой момент. Т. е. мне нужно ещё дополнительную логику для отслеживания количества прошедших тиков таймера. Короче говоря, вы предлагаете организовать ту же анимацию, только вручную, с неизбежными косякам, которые наверняка всплывут, и код только усложнится.

У меня же всё готово уже - весь "движок" в части перемещений, и надо только решить проблему, которую я вначале описал.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37566624
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне приходилось импортировать компонент таймер из форм, т. к. больше никаких свободно доступных таймеров в WPF нету. Те таймеры, что отвечают за анимацию WPF - до них не добраться. Тем более непонятно, как их использовать отдельно от анимации.
Плюс, таймер из форм имеет точность где-то 16 мс, что примерно и соответствует WPFфовским 60 кадрам в секунду. Но вот как формовский таймер отрабатывает значения, не кратные 16 мс - это вопрос. На сколько я знаю, он просто пропускает (не успевает тикнуть) все не кратные 16 мс... ну или приводит каждый следующий тик к значению, кратному 16 мс. Короче, баг. А вот WPFфовский таймер не факт, что имеет квант в 16 мс.
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37566630
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexeiKделаешь переменную: направление движения.
Ну и ещё я могу сказать, что мой движок перемещений по клеткам сделан из движка свободных перемещений в любом направлении на любое расстояние (заделка на будущее, если я захочу поменять модель перемещений). Вычислений всего чуток больше, а потенциальная функциональность закладывается огромная.

Вот мои функции.

Движения вперёд-назад - только изменение позиции, ЕЩЁ НЕ АНИМАЦИЯ. Формулы взял у одного дяди в Интернете в свободном доступе, но, как видите, они тривиальны и из единичной окружности и прямоугольного треугольника выводятся. Вверху-вниз смотреть нельзя.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
/// <summary>
        /// Changes character position.
        /// </summary>
        /// <param name="distance">The distance traveled by character.</param>
        public void Move(double distance)
        {
            Position = new Point3D(
                Position.X + System.Math.Sin(HAngle * Math.PI / 180) * distance,
                Position.Y + 0,
                Position.Z + System.Math.Cos(HAngle * Math.PI / 180) * distance);
        }



Повороты:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
/// <summary>
        /// Changes character look direction.
        /// </summary>
        /// <param name="angle">The horizontal angle at which the character looks now.</param>
        public void Turn(double hAngle)
        {
            // It is not distance of movement. It is just accessory value to calculate the look direction vector.
            double distanceToPointToLook = 1;

            HAngle += hAngle;
            LookDirection = new Vector3D(
                System.Math.Sin(HAngle * Math.PI / 180) * distanceToPointToLook,
                0,
                System.Math.Cos(HAngle * Math.PI / 180) * distanceToPointToLook);
        }



Вот обработчик нажатия любой клавиши направления - тут уже запускаются анимации:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Up:
                    player.Move(1);
                    playerCamera.BeginAnimation(
                        PerspectiveCamera.PositionProperty,
                        new System.Windows.Media.Animation.Point3DAnimation(
                            player.Position,
                            new Duration(new TimeSpan(0, 0, 0, 0, 500))));
                    break;
                case Key.Down:
                    player.Move(-1);
                    playerCamera.BeginAnimation(
                        PerspectiveCamera.PositionProperty,
                        new System.Windows.Media.Animation.Point3DAnimation(
                            player.Position,
                            new Duration(new TimeSpan(0, 0, 0, 0, 500))));
                    break;
                case Key.Left:
                    player.Turn(90);
                    playerCamera.BeginAnimation(
                        PerspectiveCamera.LookDirectionProperty,
                        new System.Windows.Media.Animation.Vector3DAnimation(
                            player.LookDirection,
                            new Duration(new TimeSpan(0, 0, 0, 0, 500))));
                    break;
                case Key.Right:
                    player.Turn(-90);
                    playerCamera.BeginAnimation(
                        PerspectiveCamera.LookDirectionProperty,
                        new System.Windows.Media.Animation.Vector3DAnimation(
                            player.LookDirection,
                            new Duration(new TimeSpan(0, 0, 0, 0, 500))));
                    break;
                default:
                    break;
            }
        }
...
Рейтинг: 0 / 0
Блокировка запуска анимации до её окончания
    #37566634
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Формулы взял у одного дяди в Интернете в свободном доступе

Ну, немного под себя изменил. )
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Блокировка запуска анимации до её окончания
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]