Сегодня рассмотрим ещё один момент работы с MS Agent в Delphi. Научимся получать список доступных анимаций для персонажа.
Дело в том, что помимо стандартных анимаций типа Move, Show, Hide и пр. любой персонаж может содержать свой уникальный набор анимаций, которые могут в значительной степини повысить реалистичность поведения персонажа на экране монитора.
В качестве практической работы, я предлагаю разработать небольшое приложение, с помощью которого мы и будем просматривать анимации персонажей.В будущем это приложение может Вам очень пригодиться для выбора набора анимаций персонажа в своих приложениях.
Итак, запускаем Delphi, создаем новый проект и размещаем на форме 2 компонента Memo, 1 ListBox, 1 Bevel, 1 Edit, 1 Button, 1 OpenDialog и, естественно, Agent. У меня получился следующий вид приложения:
При работе с программой мы будем запрашивать следующую информацию:
- Имя персонажа
- Версию набора анимаций
- Описание персонажа
- Дополнительные данные по персонажу
- Список анимаций
Дополнительно при выборе в списке анимации будем её проигрывать.
Теперь заводим глобальную переменную:
Char: IAgentCtlCharacterEx;
В обработчике события Button1Click единственной кнопки пишем следующий код:
Agent1.Characters.Load('MyAgent',OpenDialog1.FileName) ; Edit1.Text:=OpenDialog1.FileName; Char:=Agent1.Characters.Character('MyAgent') as IAgentCtlCharacterEx; Char.MoveTo(Form1.Left, Form1.Top+70, 1000); Char.Show(0); label7.Caption:=Char.Name; label8.Caption:=Char.Version; Memo1.Lines.Clear; Memo1.Text:=Char.Description; Memo2.Clear; Memo2.Text:=Char.ExtraData;
Прошу обратить Ваше внимание а строку:
Char.MoveTo(Form1.Left, Form1.Top+70, 1000);
Если судить строго — то за такую запись меня следовало бы расстрелять :) Дело в том, что здесь мы ещё не показывая персонаж пользователю перемещаем его в необходимое место — в данном случае в центр Bevel’а. Если следовать всем правилам, то вместо Form1.Top+70 следует программно определять необходимую координату, чтобы не было никаких +70 +100 и пр. констант.
Теперь переходим к анимациям. Здесь, надо сказать, без бутылки не разобраться. Список всех доступных анимаций содержится в коллекции AnimationNames расширенного интерфейса объекта Character. Если вы попробуете обратиться к коллекции напрямую — ничего хорошего не выйдет (см. рисунок)
Можете просмотреть все доступные свойства и методы у AnimationNames, но Вы не найдёте ни одного, который возвращал бы string или что-нибудь более менее читабельное. И вот тут нам потребуется модуль ActiveX. Подключаем его в uses и пишем «хитрую» процедурку, которая будет выводить в список все доступные анимации персонажа:
procedure TForm1.GetAgentAnimations; var i:integer; AEnum: IEnumVARIANT; V: OleVariant; flag:cardinal; begin Char.AnimationNames.Enum.QueryInterface(IEnumVariant, AEnum); ListBox1.Clear; AEnum.Reset; repeat AEnum.Next(1,V,flag); if VarToStr(V)<>'' then ListBox1.Items.Add(V); until flag=0; end;
Обратите внимание на переменную AEnum — собственно это интерфейс необходимый нам для перечисления всех свойств персонажа. Без подключения модуля ActiveX его нет. Спрашивается — как неискушенному в вопросах MS Agent программисту догадаться использовать интерфейс IEnumVARIANT? А никак. Для этого как минимум надо знать VC++ и уметь работать там с агентами. Благо есть ещё добрые люди, которые подсказали мне как получать списки анимаций. Теперь и вы знаете :).
Остался последний момент — проиграть анимацию из списка. Нет ничего проще. Пишем:
procedure TForm1.ListBox1Click(Sender: TObject); begin Char.Stop(EmptyParam); Char.Play(ListBox1.Items.Strings[ListBox1.ItemIndex]) end;
Здесь мы сначала прерываем уже запущенную анимацию (если она есть) и проигрываем необходимую нам. Если Вы все сделали правильно, то вид приложения после запуска будет примерно следующим:
[…] свойств персонажей, мог заметить, что в списке доступных анимаций практически у каждого персонажа есть […]