Компьютерная графика, мультимедиа и игры на Visual C#

       

Вывод на экран выступлений и анимаций всех персонажей


Листинг 48.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";



//Объявляем член интерфейса Agent:

private AgentObjects.Agent myAgentController;

//Глобальная переменная для любого текста персонажа:

static String mySpeech;

//Объявляем общую для персонажей объектную переменную:

Object myObject = null;

А в шаблон (метода Form1_Load) записываем наш код (согласно постановке задачи для всех персонажей), и метод Form1_Load принимает такой вид.

                                                       

Листинг 48.2. Загрузка персонажей в элементы управления.

private void Form1_Load(object sender, 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);

      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, true, true);
      myMerlin.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
      myPeedy.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
      myRobby.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
      //Задаем, например, Джину выполнение еще команды,
      //для примера, голосовой команды "Merlin":
      mySpeech = "Merlin";
      myGenie.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
      //Задаем, например, Магу выполнение еще команды,
      //для примера, голосовой команды "Peedy":
      mySpeech = "Peedy";
      myMerlin.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
      //Задаем, например, Попугаю выполнение еще команды,
      //для примера, голосовой команды "Robby":
      mySpeech = "Robby";
      myPeedy.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
      //Задаем, например, Роботу выполнение еще команды,
      //для примера, голосовой команды "Genie":
      mySpeech = "Genie";
    myRobby.Commands.Add(
            mySpeech, mySpeech, mySpeech, true, true);
    //Добавляем имя анимации, активизируемое голосом:
    mySpeech = "Announce";


    myGenie.Commands.Add(
    mySpeech, mySpeech, mySpeech, true, true);
    //Показываем какой-либо текущий персонаж:
    //От начала координат в вехнем левом углу панели Form1
    //задаем координаты "x,y" места расположения
    //текущего персонажа, например, Genie:
    myGenie.MoveTo(
            Convert.ToInt16(this.Location.X + 400),
            Convert.ToInt16(this.Location.Y - 130), 1000);
    //Показываем персонаж в заданном месте:
    myGenie.Show(0);
    //Чтобы персонажи произносили речи через динамики,
    //задаем им следующие свойства:
    myAgentController = new AgentObjects.Agent();
    myAgentController.Connected = true;
    myAgentController.Characters.Load(
         "genie", "genie.acs");
    myGenie =
           myAgentController.Characters.Character("genie");
    myAgentController.Characters.Load(
         "merlin", "merlin.acs");
    myMerlin =
           myAgentController.Characters.Character("merlin");
    myAgentController.Characters.Load(
         "peedy", "peedy.acs");
    myPeedy =
           myAgentController.Characters.Character("peedy");
    myAgentController.Characters.Load(
         "robby", "robby.acs");
    myRobby =
           myAgentController.Characters.Character("robby");
    //Текущий персонаж произносит текст из кода
    //и показывает этот текст в виде подсказки:
    myGenie.Speak("Здравствуйте. Меня зовут Джин. " +
    "Выберите, пожалуйста, персонаж, анимацию, " +
    "запишите слова в окно и щелкните кнопку.", myObject);
    //Добавляем в окно со списком ComboBox1
    //имена CharacterID четырех персонажей:
    comboBox1.Items.Add("Genie");
    comboBox1.Items.Add("Merlin");
    comboBox1.Items.Add("Peedy");
    comboBox1.Items.Add("Robby");
}
В панели Properties выбираем заголовок comboBox1 (или щелкаем по элементу управления comboBox1) и на вкладке Events дважды щелкаем по имени события SelectedIndexChanged. Появляется файл Form1.cs с шаблоном, который после записи нашего кода (согласно алгоритму) принимает следующий вид.


Листинг 48.3. Метод для окна со списком comboBox1.
private void comboBox1_SelectedIndexChanged(
      object sender, EventArgs e)
{
    //Добавляем имена анимаций для выделенного
    //(в окне со списком comboBox1) персонажа
    //в окно со списком comboBox2:
    We_Get_AnimationNames();
}
Чтобы это добавление имен анимаций (для выделенного в окне со списком comboBox1 персонажа) в окно со списком comboBox2 можно было вставлять в другие приложения, оформим это добавление в виде отдельного метода We_Get_AnimationNames, как показано на следующем листинге.
Листинг 48.4. Метод We_Get_AnimationNames.
private void We_Get_AnimationNames()
{
    //Объявляем перечислители myEnumerator
    //интерфейса IEnumerator
    //для имен анимаций каждого персонажа:
    System.Collections.IEnumerator myEnumerator1 =
            axAgent1.Characters.Character("Genie").
            AnimationNames.GetEnumerator();
    System.Collections.IEnumerator myEnumerator2 =
            axAgent2.Characters.Character("Merlin").
            AnimationNames.GetEnumerator();
    System.Collections.IEnumerator myEnumerator3 =
            axAgent3.Characters.Character("Peedy").
            AnimationNames.GetEnumerator();
    System.Collections.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)
    {
        //Очищаем окно со списком 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.cs с шаблоном, который после записи нашего кода (согласно алгоритму) принимает следующий вид.


Листинг 48.5. Метод для окна со списком comboBox2.
private void comboBox2_SelectedIndexChanged(
      object sender, EventArgs e)
{
    //Персонаж произносит текст
    //и показывает анимацию при условии:
    //Если в окне со списком comboBox1
    //выбран новый персонаж:
    if (comboBox1.SelectedIndex == 0)
    {
        //Скрываем все другие персонажи:
        myMerlin.Hide(0);
        myPeedy.Hide(0);
        myRobby.Hide(0);
        //Останавливаем текущую анимацию:
        myGenie.StopAll(myObject);
        //От начала координат в вехнем левом углу Form1
        //задаем координаты "x, y" _
        //места расположения нового персонажа:
        myGenie.MoveTo(
            Convert.ToInt16(this.Location.X + 750),
            Convert.ToInt16(this.Location.Y + 250), 1000);
        //Показываем новый персонаж:
        myGenie.Show(0);
        //Перед анимацией персонаж произносит "Слушаюсь":
        mySpeech = "Слушаюсь.";
        myGenie.Speak(mySpeech, myObject);
        //Показываем выделенную нами анимацию персонажа:
        myGenie.Play(comboBox2.SelectedItem.ToString());
        //Показываем анимацию персонажа в покое:
        myGenie.Play("RestPose");
    }
    //Если в окне со списком comboBox1
    //выбран новый персонаж:
    if (comboBox1.SelectedIndex == 1)
    {
        //Скрываем все другие персонажи:
        myGenie.Hide(0);
        myPeedy.Hide(0);
        myRobby.Hide(0);
        //Останавливаем текущую анимацию:
        myMerlin.StopAll(myObject);
        //От начала координат в вехнем левом углу Form1
        //задаем координаты "x, y" _
        //места расположения нового персонажа:
        myMerlin.MoveTo(
            Convert.ToInt16(this.Location.X + 750),
            Convert.ToInt16(this.Location.Y + 250), 1000);
        //Показываем новый персонаж:
        myMerlin.Show(0);
        //Перед анимацией персонаж произносит "Слушаюсь":
        mySpeech = "Слушаюсь.";


            myMerlin.Speak(mySpeech, myObject);
            //Показываем выделенную нами анимацию персонажа:
        myMerlin.Play(comboBox2.SelectedItem.ToString());
        //Показываем анимацию персонажа в покое:
        myMerlin.Play("RestPose");
    }
    //Если в окне со списком comboBox1
    //выбран новый персонаж:
    if (comboBox1.SelectedIndex == 2)
    {
        //Скрываем все другие персонажи:
        myGenie.Hide(0);
        myMerlin.Hide(0);
        myRobby.Hide(0);
        //Останавливаем текущую анимацию:
        myPeedy.StopAll(myObject);
        //От начала координат в вехнем левом углу Form1
        //задаем координаты "x, y" _
        //места расположения нового персонажа:
        myPeedy.MoveTo(
            Convert.ToInt16(this.Location.X + 750),
            Convert.ToInt16(this.Location.Y + 250), 1000);
        //Показываем новый персонаж:
        myPeedy.Show(0);
        //Перед анимацией персонаж произносит "Слушаюсь":
        mySpeech = "Слушаюсь.";
        myPeedy.Speak(mySpeech, myObject);
        //Показываем выделенную нами анимацию персонажа:
        myPeedy.Play(comboBox2.SelectedItem.ToString());
        //Показываем анимацию персонажа в покое:
        myPeedy.Play("RestPose");
    }
    //Если в окне со списком comboBox1
    //выбран новый персонаж:
    if (comboBox1.SelectedIndex == 3)
    {
        //Скрываем все другие персонажи:
        myGenie.Hide(0);
        myMerlin.Hide(0);
        myPeedy.Hide(0);
        //Останавливаем текущую анимацию:
        myRobby.StopAll(myObject);
        //От начала координат в вехнем левом углу Form1
        //задаем координаты "x, y" _
        //места расположения нового персонажа:
        myRobby.MoveTo(
            Convert.ToInt16(this.Location.X + 750),
            Convert.ToInt16(this.Location.Y + 250), 1000);
        //Показываем новый персонаж:
        myRobby.Show(0);
        //Перед анимацией персонаж произносит "Слушаюсь":


        mySpeech = "Слушаюсь.";
        myRobby.Speak(mySpeech, myObject);
        //Показываем выделенную нами анимацию персонажа:
        myRobby.Play(comboBox2.SelectedItem.ToString());
        //Показываем анимацию персонажа в покое:
        myRobby.Play("RestPose");
      }
}
Теперь, следуя алгоритму в первом параграфе, мы записываем такой код, чтобы:
если мы щелкнем кнопку на форме, но ничего не запишем в окно TextBox, то персонаж попросит нас записать текст в это окно;
когда мы запишем в окно TextBox текст на русском языке и щелкнем кнопку на форме, то персонаж произнесет записанный нами текст.
Дважды щелкаем эту кнопку в режиме редактирования (или в панели Properties выбираем заголовок button1 и на вкладке Events дважды щелкаем по имени события Click). Появляется файл Form1.cs с шаблоном (метода button1_Click), который после записи нашего кода принимает следующий вид.
Листинг 48.6. Метод для кнопки.
private void button1_Click(object sender, EventArgs e)
{
      //Чтобы персонажи произносили речи через динамики,
      //задаем им следующие свойства:
      myAgentController = new AgentObjects.Agent();
      myAgentController.Connected = true;
      myAgentController.Characters.Load(
             "genie", "genie.acs");
      myGenie =
            myAgentController.Characters.Character("genie");
      myAgentController.Characters.Load(
             "merlin", "merlin.acs");
      myMerlin =
           myAgentController.Characters.Character("merlin");
      myAgentController.Characters.Load(
             "peedy", "peedy.acs");
      myPeedy =
            myAgentController.Characters.Character("peedy");
      myAgentController.Characters.Load(
             "robby", "robby.acs");
      myRobby =
            myAgentController.Characters.Character("robby");
      //Персонаж произносит текст из окна TextBox


      //при условии:
      // Если окно TextBox не заполнено:
      if (textBox1.Text == "")
      {
        if (comboBox1.SelectedIndex == 0)
        {
            mySpeech =
            "Запишите, пожалуйста, в окно слова, " +
            "которые я должен произнести.";
            myGenie.Speak(mySpeech, myObject);
        }
        if (comboBox1.SelectedIndex == 1)
        {
            mySpeech =
            "Запишите, пожалуйста, в окно слова, " +
            "которые я должен произнести.";
            myMerlin.Speak(mySpeech, myObject);
        }
        if (comboBox1.SelectedIndex == 2)
        {
            mySpeech =
            "Запишите, пожалуйста, в окно слова, " +
            "которые я должен произнести.";
            myPeedy.Speak(mySpeech, myObject);
        }
        if (comboBox1.SelectedIndex == 3)
        {
            mySpeech =
            "Запишите, пожалуйста, в окно слова, " +
            "которые я должен произнести.";
            myRobby.Speak(mySpeech, myObject);
        }
      }
      else
      //иначе, если окно TextBox заполнено,
      //персонаж произносит слова из этого TextBox:
      {
            mySpeech = textBox1.Text;
            if (comboBox1.SelectedIndex == 0)
            myGenie.Speak(mySpeech, myObject);
            if (comboBox1.SelectedIndex == 1)
            myMerlin.Speak(mySpeech, myObject);
            if (comboBox1.SelectedIndex == 2)
            myPeedy.Speak(mySpeech, myObject);
            if (comboBox1.SelectedIndex == 3)
            myRobby.Speak(mySpeech, myObject);
      }
}
В предыдущей главе мы привели методику и программу для управления персонажами при помощи наших голосовых команд: когда мы произнесем в микрофон по-английски: заданную по умолчанию команду Hide (Скрыть), персонаж удаляется с экрана; одно из заданных по умолчанию имен персонажей (Genie, Merlin, Peedy, Robby), этот озвученный персонаж сменяет предыдущий; заданную нами пользовательскую голосовую команду, например, MoveToMouse, персонаж перемещается в место нахождения курсора мыши.


По изложенной в предыдущей главе методике здесь мы продолжим разработку методов управления персонажами при помощи голосовых команд. Напомним, что на листинге 48.2 в метод Form1_Load мы добавили новую голосовую команду в виде имени анимации (это имя имеется в окне со списком сomboBox2 для любого персонажа), чтобы видимый на экране персонаж произнес поясняющий текст и выполнил эту анимацию. К примеру, на листинге 48.2 для персонажа Genie (Джин) мы добавили имя анимации Announce в следующем коде:
    //Добавляем имя анимации, активизируемое голосом:
    mySpeech = "Announce";
    myGenie.Commands.Add(
    mySpeech, mySpeech, mySpeech, true, true);
Таким образом, чтобы после произнесения в микрофон имени анимации Announce персонаж выполнил эту анимацию, в панели Properties выбираем заголовок AxAgent1 (или щелкаем по элементу управления AxAgent1) и на вкладке Events дважды щелкаем по имени события Command. Появляется файл Form1.cs с шаблоном, который после записи нашего кода (согласно алгоритму) принимает такой вид.
Листинг 48.7. Метод, чтобы персонаж выполнял наши голосовые команды.
//Объявляем глобальный объект myCommand интерфейса
static AgentObjects.IAgentCtlUserInput myCommand;
private void axAgent1_Command(object sender,
      AxAgentObjects._AgentEvents_CommandEvent e)
{
      //Связываем объект myCommand с голосом пользователя:
      myCommand = (AgentObjects.IAgentCtlUserInput)
            (e.userInput);
      //Если выше при помощи метода Add мы добавили
      //имя анимации, например, Announce
      //в качестве голосовой команды:
      if (myCommand.Voice == "Announce")
      {
          //После голосовой команды останавливаем
          //текущую анимацию:
          myGenie.StopAll(myObject);
          //Перед анимацией персонаж произносит:
          mySpeech = "Охотно покажу эту анимацию.";
          myGenie.Speak(mySpeech, myObject);
          //Показывает анимацию, имя которой
          //мы произнесли в микрофон:


          myGenie.Play("Announce");
          //Показывает анимацию в покое:
          myGenie.Play("RestPose");
      }
      //После команды голосом "MoveToMouse"
      // персонаж перемещается на место курсора мыши:
      if (myCommand.Voice == "MoveToMouse")
      {
            myGenie.MoveTo(
                        Convert.ToInt16(Cursor.Position.X),
                  Convert.ToInt16(Cursor.Position.Y), 1000);
      }
}
Поясним, что выше на листинге 48.2 в метод Form1_Load мы добавили голосовую команду MoveToMouse, поэтому в данном листинге приводим код для обработки также и этой команды (этот код подробно объяснен в предыдущей главе).
Аналогично мы можем записать код для решения любой подобной задачи согласно разработанному нами алгоритму, в том числе для выполнения любой анимации любого персонажа по нашей голосовой команде.
Cтроим программу и запускаем на выполнение обычным образом: Build, Build Solution; Debug, Start Without Debugging. В ответ Visual C# выполняет программу и на рабочий стол выводит форму Form1 в режиме выполнения.
И теперь на основании предыдущих глав разработаем методику создания мультфильма с использованием этих персонажей и их анимаций.

Содержание раздела