Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005
.pdf210 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
записи нашего кода принимает такой вид.
Листинг 39.10. Метод для кнопки “Скрыть Робота”.
private:
System::Void button8_Click(System::Object^ sender, System::EventArgs^ e)
{
//Скрыть персонаж: myRobby->Hide(0);
}
Листинг 39.11. Метод, обрабатывающий щелчок по персонажу Genie.
private: System::Void axAgent1_ClickEvent(System::Object^ sender, AxAgentObjects::_AgentEvents_ClickEvent^ e)
{
//Персонаж выполняет анимацию Confused: myGenie->Play("Confused");
//Персонаж произносит текст: mySpeech = "Есть проблемы?"; myGenie->Speak(mySpeech, nullptr);
//Персонаж выполняет анимацию RestPose: myGenie->Play("RestPose");
}
Листинг 39.12. Метод, обрабатывающий щелчок по персонажу Merlin.
private: System::Void axAgent2_ClickEvent( System::Object^ sender, AxAgentObjects::_AgentEvents_ClickEvent^ e)
{
//Персонаж выполняет анимацию Confused: myMerlin->Play("Confused");
//Персонаж произносит текст: mySpeech = "Имеются проблемы?"; myMerlin->Speak(mySpeech, nullptr);
//Персонаж выполняет анимацию RestPose: myMerlin->Play("RestPose");
}
Листинг 39.13. Метод, обрабатывающий щелчок по персонажу Peedy.
private: System::Void axAgent3_ClickEvent( System::Object^ sender, AxAgentObjects::_AgentEvents_ClickEvent^ e)
{
//Персонаж выполняет анимацию Confused:
Глава 39. Методика управления мультипликационными персонажами |
211 |
myPeedy->Play("Confused"); //Персонаж произносит текст: mySpeech = "Попка умный "
"и хочет есть."; myPeedy->Speak(mySpeech, nullptr); //Персонаж выполняет анимацию RestPose: myPeedy->Play("RestPose");
}
Листинг 39.14. Метод, обрабатывающий щелчок по персонажу Robby.
private: System::Void axAgent4_ClickEvent( System::Object^ sender, AxAgentObjects::_AgentEvents_ClickEvent^ e)
{
//Персонаж выполняет анимацию Confused: myRobby->Play("Confused");
//Персонаж произносит текст: mySpeech = "Что-то надо починить?"; myRobby->Speak(mySpeech, nullptr);
//Персонаж выполняет анимацию RestPose: myRobby->Play("RestPose");
}
Листинг 39.15. Метод, чтобы Джин выполнял наши голосовые команды.
//Объявляем глобальный объект myCommand интерфейса //IAgentCtlUserInput для всех последующих методов: static AgentObjects::IAgentCtlUserInput^ myCommand; private:
System::Void axAgent1_Command(System::Object^ sender, AxAgentObjects::_AgentEvents_CommandEvent^ e)
{
//Связываем объект myCommand с голосом пользователя: myCommand = static_cast< AgentObjects::IAgentCtlUserInput^>(e->userInput); //После команды голосом "MoveToMouse"
//персонаж перемещается на место курсора мыши: if (0==myCommand->Name->CompareTo("MoveToMouse"))
{
myGenie->MoveTo(Cursor->Position.X, Cursor->Position.Y, 1000);
}
//После команды голосом "Merlin"
//прежний персонаж скрывается, а новый появляется: if (0==myCommand->Name->CompareTo("Merlin"))
{
212 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
//Скрыть прежний персонаж: myGenie->Hide(0);
//От начала координат в верхнем левом углу Form1 //задаем координаты "x,y" места нового персонажа: myMerlin->MoveTo(
Convert::ToInt16(this->Location.X + 400), Convert::ToInt16(this->Location.Y - 130), 1000);
//Показать новый персонаж в заданном месте: myMerlin->Show(0);
//Новый персонаж произносит речь: mySpeech = "Я - Маг. Есть проблемы?"; myMerlin->Speak(mySpeech, nullptr);
}
}
Листинг 39.16. Метод, чтобы Маг выполнял наши голосовые команды.
private:
System::Void axAgent2_Command(System::Object^ sender, AxAgentObjects::_AgentEvents_CommandEvent^ e)
{
//Связываем объект myCommand с голосом пользователя: myCommand = static_cast< AgentObjects::IAgentCtlUserInput^>(e->userInput); //После команды голосом "MoveToMouse"
//персонаж перемещается на место курсора мыши: if (0==myCommand->Name->CompareTo("MoveToMouse"))
{
myMerlin->MoveTo(Cursor->Position.X, Cursor->Position.Y, 1000);
}
//После команды голосом "Peedy"
//прежний персонаж скрывается, а новый появляется: if (0==myCommand->Name->CompareTo("Peedy"))
{
//Скрыть прежний персонаж: myMerlin->Hide(0);
//От начала координат в верхнем левом углу Form1 //задаем координаты "x,y" места нового персонажа:
myPeedy->MoveTo( Convert::ToInt16(this->Location.X + 400), Convert::ToInt16(this->Location.Y - 130), 1000);
//Показать новый персонаж в заданном месте: myPeedy->Show(0);
//Новый персонаж произносит речь: mySpeech = "Я - Попугай. Есть проблемы?"; myPeedy->Speak(mySpeech, nullptr);
Глава 39. Методика управления мультипликационными персонажами |
213 |
}
}
Аналогично (для следующего персонажа) в панели Properties выбираем заголовок следующего элемента управления axAgent3 и на вкладке Events дважды щелкаем по имени события Command.
Появляется файл Form1.h с шаблоном (метода axAgent3_Command), который после записи нашего кода (согласно алгоритму) принимает следующий вид.
Листинг 39.17. Метод, чтобы Попугай выполнял наши голосовые команды.
private:
System::Void axAgent3_Command(System::Object^ sender, AxAgentObjects::_AgentEvents_CommandEvent^ e)
{
//Связываем объект myCommand с голосом пользователя: myCommand = static_cast< AgentObjects::IAgentCtlUserInput^>(e->userInput); //После команды голосом "MoveToMouse"
//персонаж перемещается на место курсора мыши: if (0==myCommand->Name->CompareTo("MoveToMouse"))
{
myPeedy->MoveTo(Cursor->Position.X, Cursor->Position.Y, 1000);
}
//После команды голосом "Peedy"
//прежний персонаж скрывается, а новый появляется: if (0==myCommand->Name->CompareTo("Robby"))
{
//Скрыть прежний персонаж: myPeedy->Hide(0);
//От начала координат в верхнем левом углу Form1 //задаем координаты "x,y" места нового персонажа:
myRobby->MoveTo( Convert::ToInt16(this->Location.X + 400), Convert::ToInt16(this->Location.Y - 130), 1000);
//Показать новый персонаж в заданном месте: myRobby->Show(0);
//Новый персонаж произносит речь: mySpeech = "Я - Робот. Есть проблемы?"; myRobby->Speak(mySpeech, nullptr);
}
}
Аналогично (для следующего персонажа) в панели Properties выбираем заголовок следующего элемента управления axAgent4 и на вкладке Events дважды щелкаем по имени события Command.
Появляется файл Form1.h с шаблоном (метода axAgent4_Command), который по-
214 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
сле записи нашего кода (согласно алгоритму) принимает следующий вид.
Листинг 39.18. Метод, чтобы Робот выполнял наши голосовые команды.
private:
System::Void axAgent4_Command(System::Object^ sender, AxAgentObjects::_AgentEvents_CommandEvent^ e)
{
//Связываем объект myCommand с голосом пользователя: myCommand = static_cast< AgentObjects::IAgentCtlUserInput^>(e->userInput); //После команды голосом "MoveToMouse"
//персонаж перемещается на место курсора мыши: if (0==myCommand->Name->CompareTo("MoveToMouse"))
{
myRobby->MoveTo(Cursor->Position.X, Cursor->Position.Y, 1000);
}
//После команды голосом "Peedy"
//прежний персонаж скрывается, а новый появляется: if (0==myCommand->Name->CompareTo("Genie"))
{
//Скрыть прежний персонаж: myRobby->Hide(0);
//От начала координат в верхнем левом углу Form1 //задаем координаты "x,y" места нового персонажа: myGenie->MoveTo(
Convert::ToInt16(this->Location.X + 400), Convert::ToInt16(this->Location.Y - 130), 1000);
//Показать новый персонаж в заданном месте: myGenie->Show(0);
//Новый персонаж произносит речь: mySpeech = "Я - Джин. Есть проблемы?"; myGenie->Speak(mySpeech, nullptr);
}
}
Глава 40. Вывод на экран выступлений и анимаций всех персонажей
Листинг 40.1. Объявление членов интерфейса и глобальных переменных.
//Персонаж по имени Джин (Genie) и путь к его файлу: static AgentObjects::IAgentCtlCharacterEx^ myGenie; static String^ DATAPATH_1 = "Genie.acs";
//Персонаж по имени Маг (Merlin) и путь к его файлу: static AgentObjects::IAgentCtlCharacterEx^ myMerlin; static String^ DATAPATH_2 = "Merlin.acs";
//Персонаж по имени Попугай (Peedy) и путь к его файлу: static AgentObjects::IAgentCtlCharacterEx^ myPeedy; static String^ DATAPATH_3 = "Peedy.acs";
//Персонаж по имени Робот (Robby) и путь к его файлу: static AgentObjects::IAgentCtlCharacterEx^ myRobby; static String^ DATAPATH_4 = "Robby.acs";
//Глобальная переменная для любого текста персонажа: static String^ mySpeech;
А в шаблон (метода Form1_Load) записываем наш код (согласно постановке задачи для всех персонажей), и метод Form1_Load принимает такой вид.
Листинг 40.2. Загрузка персонажей в элементы управления.
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
//Загружаем персонаж в элемент управления axAgent1: axAgent1->Characters->Load("Genie", DATAPATH_1); myGenie = axAgent1->Characters->Character("Genie"); //Чтобы он выполнял голосовые команды на англ. яз.: myGenie->LanguageID = 0x409;
//Загружаем персонаж в элемент управления axAgent2: axAgent2->Characters->Load("Merlin", DATAPATH_2); myMerlin = axAgent2->Characters->Character("Merlin"); //Чтобы он выполнял голосовые команды на англ. яз.: myMerlin->LanguageID = 0x409;
//Загружаем персонаж в элемент управления axAgent3: axAgent3->Characters->Load("Peedy", DATAPATH_3);
216 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
myPeedy = axAgent3->Characters->Character("Peedy"); //Чтобы он выполнял голосовые команды на англ. яз.: myPeedy->LanguageID = 0x409;
//Загружаем персонаж в элемент управления axAgent4: axAgent4->Characters->Load("Robby", DATAPATH_4); myRobby = axAgent4->Characters->Character("Robby"); //Чтобы он выполнял голосовые команды на англ. яз.: myRobby->LanguageID = 0x409;
//Для всех четырех персонажей добавляем //нашу голосовую команду, как пользователей, //например, команду "MoveToMouse" - //переместиться на место курсора мыши: mySpeech = "MoveToMouse"; myGenie->Commands->Add(
mySpeech, mySpeech, mySpeech, nullptr, nullptr); myMerlin->Commands->Add(
mySpeech, mySpeech, mySpeech, nullptr, nullptr); myPeedy->Commands->Add(
mySpeech, mySpeech, mySpeech, nullptr, nullptr); myRobby->Commands->Add(
mySpeech, mySpeech, mySpeech, nullptr, nullptr);
//Добавляем имя анимации, например, Announce, //активизируемую нашей голосовой командой: mySpeech = "Announce";
myGenie->Commands->Add(
mySpeech, mySpeech, mySpeech, nullptr, nullptr);
//Показываем какой-либо текущий персонаж:
//От начала координат в вехнем левом углу формы Form1 //задаем координаты "x, y" места расположения //текущего персонажа, например, Джина (Genie):
myGenie->MoveTo(Convert::ToInt16(this->Location.X + 750), Convert::ToInt16(this->Location.Y + 250), 0);
//Показываем персонаж в заданном месте: myGenie->Show(0);
//Текущий персонаж произносит текст из кода //и показывает этот текст в виде подсказки: mySpeech = "Здравствуйте. Меня зовут Джин. "
"Выберите, пожалуйста, персонаж, анимацию, " "запишите слова в окно и щелкните кнопку.";
myGenie->Speak(mySpeech, nullptr); //Добавляем в окно со списком ComboBox1 //имена CharacterID четырех персонажей:
Глава 40. Вывод на экран выступлений и анимаций всех персонажей |
217 |
String^ myCharacterName; myCharacterName = "Genie"; comboBox1->Items->Add(myCharacterName);
myCharacterName = "Merlin"; comboBox1->Items->Add(myCharacterName);
myCharacterName = "Peedy"; comboBox1->Items->Add(myCharacterName);
myCharacterName = "Robby"; comboBox1->Items->Add(myCharacterName);
}
Теперь, следуя алгоритму в первом параграфе, мы записываем такой код, чтобы: если в левом окне со списком ComboBox1 из четырех персонажей (Genie, Merlin,
Peedy, Robby) мы выбираем какой-либо один персонаж,
в правое окно со списком ComboBox2 программа заносила (из тех компонентов, которые мы загрузили в наш компьютер из Интернета по описанной выше схеме) все анимации (более 70 анимаций) для выбранного персонажа.
В панели Properties выбираем заголовок comboBox1 (или щелкаем по элементу управления comboBox1) и на вкладке Events дважды щелкаем по имени события SelectedIndexChanged. Появляется файл Form1.h с шаблоном, который после записи нашего кода (согласно алгоритму) принимает следующий вид.
Листинг 40.3. Метод для окна со списком comboBox1.
private: System::Void comboBox1_SelectedIndexChanged( System::Object^ sender, System::EventArgs^ e)
{
//Добавляем имена анимаций для выделенного //(в окне со списком ComboBox1) персонажа //в окно со списком ComboBox2:
We_Get_AnimationNames();
}
Чтобы это добавление имен анимаций (для выделенного в окне со списком comboBox1 персонажа) в окно со списком comboBox2 можно было вставлять в другие приложения, оформим это добавление в виде отдельного метода We_Get_AnimationNames, как показано на следующем листинге.
Листинг 40.4. Метод We_Get_AnimationNames.
private: void We_Get_AnimationNames()
{
//Объявляем перечислители myEnumerator //интерфейсаIEnumerator
//для имен анимаций каждого персонажа:
218 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
IEnumerator^ myEnumerator1 = axAgent1->Characters->Character("Genie")-> AnimationNames->GetEnumerator();
IEnumerator^ myEnumerator2 = axAgent2->Characters->Character("Merlin")-> AnimationNames->GetEnumerator();
IEnumerator^ myEnumerator3 = axAgent3->Characters->Character("Peedy")-> AnimationNames->GetEnumerator();
IEnumerator^ myEnumerator4 = axAgent4->Characters->Character("Robby")-> AnimationNames->GetEnumerator();
//Если в окне со списком comboBox1 //выбран первый персонаж с индексом 0: if (comboBox1->SelectedIndex == 0)
{
//Очищаем окно со списком comboBox2: comboBox2->Items->Clear();
//Организовываем цикл:
while (myEnumerator1->MoveNext())
{
//Добавляем имена анимаций данного персонажа //в окно со списком comboBox2: comboBox2->Items->Add(myEnumerator1->Current);
}
}
//Если в окне со списком comboBox1 //выбран второй персонаж с индексом 1: if (comboBox1->SelectedIndex == 1)
{
//Очищаем окно со списком comboBox2: comboBox2->Items->Clear();
//Организовываем цикл:
while (myEnumerator2->MoveNext())
{
//Добавляем имена анимаций данного персонажа //в окно со списком comboBox2: comboBox2->Items->Add(myEnumerator2->Current);
}
}
//Если в окне со списком comboBox1 //выбран третий персонаж с индексом 2: if (comboBox1->SelectedIndex == 2)
Глава 40. Вывод на экран выступлений и анимаций всех персонажей |
219 |
{
//Очищаем окно со списком comboBox2: comboBox2->Items->Clear();
//Организовываем цикл:
while (myEnumerator3->MoveNext())
{
//Добавляем имена анимаций данного персонажа //в окно со списком comboBox2: comboBox2->Items->Add(myEnumerator3->Current);
}
}
//Если в окне со списком comboBox1 //выбран четвертый персонаж с индексом 3: if (comboBox1->SelectedIndex == 3)
{
//Очищаем окно со списком comboBox2: comboBox2->Items->Clear();
//Организовываем цикл:
while (myEnumerator4->MoveNext())
{
//Добавляем имена анимаций данного персонажа //в окно со списком comboBox2: comboBox2->Items->Add(myEnumerator4->Current);
}
}
}
Теперь, следуя алгоритму в первом параграфе, мы записываем такой код, чтобы: если в левом окне со списком comboBox1 из четырех персонажей (Genie, Merlin,
Peedy, Robby) мы выбираем какой-либо один персонаж,
а в правом окне со списком comboBox2 из более чем 70 анимаций мы выбираем какую-либо одну анимацию,
то на месте предыдущего персонажа появляется выбранный нами персонаж, произносит текст и выполняет выбранную нами анимацию.
В панели Properties выбираем заголовок comboBox2 (или щелкаем по элементу управления comboBox2) и на вкладке Events дважды щелкаем по имени события SelectedIndexChanged. Появляется файл Form1.h с шаблоном, который после записи нашего кода (согласно алгоритму) принимает следующий вид.
Листинг 40.5. Метод для окна со списком comboBox2.
private: System::Void comboBox2_SelectedIndexChanged( System::Object^ sender, System::EventArgs^ e)
{
//Персонаж произносит текст //и показывает анимацию при условии:
//Если в окне со списком comboBox1