Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005

.pdf
Скачиваний:
306
Добавлен:
13.08.2013
Размер:
1.14 Mб
Скачать

Глава 42. Пример Интернет-магазина на основе Microsoft Agent

На основе программ Visual C++, разработанных нами в предыдущих главах, теперь мы можем проектировать сложные интерактивные компьютерные игры, мультфильмы, Интернет-магазины и другие практические приложения.

Такое сложное приложение мы рассмотрим на примере реального интернетмагазина под названием “Peedy’s Pizza Palace”, в котором уже известный нам Попугай (Peedy) продает пиццу. Этот пример разработан самой корпорацией Microsoft на базе своей же мультимедийной программной технологии (платформы) Microsoft Agent версии 2.0.

Данный магазин создан по сценарию (постановке), который состоит из следующих основных эпизодов.

Эпизод 1. После загрузки браузера Internet Explorer в его окне автоматически появляются интерфейс магазина и его продавец в виде Попугая (Peedy).

Эпизод 2. Попугай объясняет нам, как пользоваться данным Интернетмагазином, и предлагает сделать выбор вида пиццы и дополнительной начинки.

Эпизод 3. При помощи элементов управления или голосовых команд мы выбираем какой-либо вид пиццы и дополнительной начинки и даем команду сделать нам расчет.

Эпизод 4. Попугай делает расчет, сообщает нам стоимость пиццы, перелетает на новое место и сообщает, что готов принять от нас новый заказ.

Ключевые понятия мультимедиа мы дали в предыдущих главах, поэтому здесь сразу перейдем к описанию работы магазина согласно эпизодам.

42.2. Работа магазина

Итак, чтобы изучить пример интернет-магазина под названием “Peedy’s Pizza Palace”, в котором Попугай (Peedy) продает пиццу, выполняем следующее.

1.Если мы не загрузили (бесплатно) компоненты Microsoft Agent версии 2.0, то делаем это, как описано в первой главе данной части книги.

2.Подключаемся к Интернету (если мы не подключились) при помощи браузера Internet Explorer и открываем пример по адресу:

agent.microsoft.com/agent2/sdk/samples/html/peedypza.htm

Глава 43. Построение графика по точкам эксперимента и интеграция с мультипликационными персонажами MS Agent

Листинг 43.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 принимает такой вид.

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

private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)

{

//Загружаем персонаж в элемент управления axAgent1: axAgent1->Characters->Load("Genie", DATAPATH_1); myGenie = axAgent1->Characters->Character("Genie");

//Загружаем персонаж в элемент управления axAgent2: axAgent2->Characters->Load("Merlin", DATAPATH_2); myMerlin = axAgent2->Characters->Character("Merlin");

//Загружаем персонаж в элемент управления axAgent3: axAgent3->Characters->Load("Peedy", DATAPATH_3);

232 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

myPeedy = axAgent3->Characters->Character("Peedy");

//Загружаем персонаж в элемент управления axAgent4: axAgent4->Characters->Load("Robby", DATAPATH_4); myRobby = axAgent4->Characters->Character("Robby");

//От начала координат в вехнем левом углу Form1 //задаем координаты "x, y" персонажа: myGenie->MoveTo(

Convert::ToInt16(this->Location.X + 0), Convert::ToInt16(this->Location.Y - 130), 1000);

//Показываем персонаж в заданном месте: myGenie->Show(0);

//Первый персонаж произносит текст mySpeech //и показывает этот текст в виде подсказки: mySpeech = "Сидите за монитором прямо, "

"как пианист."; myGenie->Speak(mySpeech, nullptr);

}

Чтобы следующий персонаж, например, Маг (Merlin) появился через заданное нами время, щелкаем по значку для первого компонента Timer и в панели Properties для этого компонента в свойстве Interval записываем данное время, например, 5000 миллисекунд (или 5 секунд) и запускаем таймер (в свойстве Enabled выбираем True).

Теперь дважды щелкаем по значку для этого компонента Timer (или в панели Properties на вкладке Events дважды щелкаем по имени единственного там события Tick). Появляется файл Form1.h с шаблоном (метода timer1_Tick), который после записи нашего кода принимает следующий вид.

Листинг 43.3. Метод для вызова персонажа через Interval времени.

private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)

{

//Показываем следующий персонаж рядом: myMerlin->MoveTo(

Convert::ToInt16(this->Location.X + 200), Convert::ToInt16(this->Location.Y - 130), 1000);

myMerlin->Show(0);

//Текущий персонаж произносит текст mySpeech //и показывает этот текст в виде подсказки: mySpeech = "Держите глаза от монитора "

"на расстоянии вытянутой руки."; myMerlin->Speak(mySpeech, nullptr); //Останавливаем генерирование события Tick: timer1->Enabled = false;

}

Глава 43. Построение графика по точкам и интеграция с MS Agent

233

Чтобы следующий персонаж, например, Попугай (Peedy) появился через заданное нами время, щелкаем по значку для второго компонента Timer и в панели Properties для этого компонента в свойстве Interval записываем данное время, например, 10000 миллисекунд (или 10 секунд) и запускаем таймер (в свойстве Enabled выбираем True). Теперь дважды щелкаем по значку для этого компонента Timer (или в панели Properties на вкладке Events дважды щелкаем по имени единственного там события Tick). Появляется файл Form1.h с шаблоном (метода timer2_Tick), который после записи нашего кода принимает следующий вид.

Листинг 43.4. Метод для вызова персонажа через Interval времени.

private: System::Void timer2_Tick(System::Object^ sender, System::EventArgs^ e)

{

//Показываем следующий персонаж рядом: myPeedy->MoveTo(

Convert::ToInt16(this->Location.X + 400), Convert::ToInt16(this->Location.Y - 130), 1000);

myPeedy->Show(0);

//Текущий персонаж произносит текст mySpeech //и показывает этот текст в виде подсказки:

mySpeech = "Поднимите монитор, чтобы глаза были " "на уровне верхней кромки экрана."; myPeedy->Speak(mySpeech, nullptr); //Останавливаем генерирование события Tick: timer2->Enabled = false;

}

Чтобы следующий персонаж, например, Робот (Robby) появился через заданное нами время, щелкаем по значку для третьего компонента Timer и в панели Properties для этого компонента в свойстве Interval записываем данное время, например, 15000 миллисекунд (или 15 секунд) и запускаем таймер (в свойстве Enabled выбираем True). Теперь дважды щелкаем по значку для этого компонента Timer (или в панели Properties на вкладке Events дважды щелкаем по имени единственного там события Tick). Появляется файл Form1.h с шаблоном (метода timer3_Tick), который после записи нашего кода принимает следующий вид.

Листинг 43.5. Метод для вызова персонажа через Interval времени.

private: System::Void timer3_Tick(System::Object^ sender, System::EventArgs^ e)

{

//Показываем следующий персонаж рядом: myRobby->MoveTo(

Convert::ToInt16(this->Location.X + 600), Convert::ToInt16(this->Location.Y - 130), 1000);

myRobby->Show(0);

234 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

//Текущий персонаж произносит текст mySpeech //и показывает этот текст в виде подсказки:

mySpeech = "Работайте на клавиатуре всеми пальцами."; myRobby->Speak(mySpeech, nullptr);

//Останавливаем генерирование события Tick: timer3->Enabled = false;

}

Мы записали код для вывода на экран всех четырех персонажей. Чтобы один из этих персонажей, например, Джин (Genie) периодически (с заданным нами интервалом времени в компоненте Timer) повторял инструкцию пользователю (например, о том, как строить график на данной форме), щелкаем по значку для четвертого компонента Timer и в панели Properties для этого компонента в свойстве Interval записываем данный интервал времени, например, 18000 миллисекунд (или 18 секунд) и запускаем таймер (в свойстве Enabled выбираем True). Теперь дважды щелкаем по значку для этого компонента Timer (или в панели Properties на вкладке Events дважды щелкаем по имени единственного там события Tick). Появляется файл Form1.h с шаблоном (метода timer4_Tick), который после записи нашего кода принимает следующий вид.

Листинг 43.6. Метод для произнесения инструкции через Interval времени.

private: System::Void timer4_Tick(System::Object^ sender, System::EventArgs^ e)

{

//Текущий персонаж произносит текст mySpeech //и показывает этот текст в виде подсказки:

mySpeech = "Запишите координаты точек целыми числами, " "щелкните верхнюю кнопку, и Вы увидите график. " "Чтобы стереть график, щелкните нижнюю кнопку."; myGenie->Speak(mySpeech, nullptr);

}

Мы видим, что в последнем методе, в отличие от трех предыдущих методов, мы не останавливаем генерирование события Tick (тем самым, не выключаем таймер) и даем возможность персонажу говорить до тех пор, пока мы не щелкнем по нему правой кнопкой и не выберем команду Hide (Скрыть).

Чтобы при помощи кнопки “1. Построить график” появился график функциональной зависимости y = f(x), дважды щелкаем или эту кнопку в режиме проектирования (рис. 43.1), или имя события Click в панели Properties на вкладке Events. Появляется шаблон, который после записи нашего кода принимает такой вид.

Листинг 43.7. Метод для обработки щелчка кнопки с целью рисования графика.

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)

{

//Объявляем локальные переменные:

Глава 43. Построение графика по точкам и интеграция с MS Agent

235

float x1, y1, x2, y2, x3, y3, x4, y4; float x_O, y_O, x_end, y_end; //Координаты начальной точки O:

x_O = 20; y_O = 20;

//Считываем координаты точек из окон:

x1 = Convert::ToSingle(textBox1->Text) + x_O;

y1 = -Convert::ToSingle(textBox2->Text) + pictureBox1->Height - y_O;

x2 = Convert::ToSingle(textBox3->Text) + x_O;

y2 = -Convert::ToSingle(textBox4->Text) + pictureBox1->Height - y_O;

x3 = Convert::ToSingle(textBox5->Text) + x_O;

y3 = -Convert::ToSingle(textBox6->Text) + pictureBox1->Height - y_O;

x4 = Convert::ToSingle(textBox7->Text) + x_O;

y4 = -Convert::ToSingle(textBox8->Text) + pictureBox1->Height - y_O;

//Создаем графический объект g класса Graphics: Graphics^ g;

//Связываем графический объект g класса Graphics //с элементом управления pictureBox1:

g = pictureBox1->CreateGraphics(); //Создаем перо для осей координат:

Pen^ myPenAxes = gcnew Pen(Color::Black, 1); //Строим ось координат x:

x_end = pictureBox1->Width - y_O; g->DrawLine(myPenAxes,

x_O, pictureBox1->Height - y_O, x_end, pictureBox1->Height - y_O);

//Строим ось координат y: y_end = y_O; g->DrawLine(myPenAxes,

x_O, pictureBox1->Height - y_O, x_O, y_O);

//Создаем перо для графика:

Pen^ myPen = gcnew Pen(Color::Black, 3);

//Строим график: g->DrawLine(myPen, x1, y1, x2, y2); g->DrawLine(myPen, x2, y2, x3, y3); g->DrawLine(myPen, x3, y3, x4, y4);

}

Чтобы при помощи кнопки “2. Удалить график” график функциональной зависимости y = f(x) был стерт, дважды щелкаем или эту кнопку в режиме проектирования (рис. 43.1), или имя события Click в панели Properties на вкладке Events.

236 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005

Появляется шаблон, который после записи нашего кода принимает такой вид.

Листинг 43.8. Метод для обработки щелчка по кнопке.

private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)

{

//Создаем графический объект g класса Graphics: Graphics^ g;

//Связываем графический объект g класса Graphics //с элементом управления pictureBox1:

g = pictureBox1->CreateGraphics();

//Очистить pictureBox1, заполнив белым цветом White: g->Clear(Color::White);

}

Часть VIII. Методология анимации объектов

Глава 44. Оглавление системы программ для анимации объектов

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

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

Следовательно, методика разработки анимации заключается в написании программы на основе использования стандартных методов (функций) из библиотеки классов какой-либо платформы визуального программирования и на основе математических зависимостей (без рисования последовательных фаз изменения объектов и без сохранения этих фаз в виде графических файлов).

Для разработки анимации в среде Visual C++ имеется несколько вариантов применения элементов управления и программ. Например, один из вариантов использует элемент управления StatusBar, внутри которого располагают панели, на которых размещают уже готовые анимационные рисунки из класса StatusBar.

Другой вариант основан на применении класса Matrix (из пространства имен System::Drawing::Drawing2D), который (при помощи своих методов) производит преобразования (перемещение, поворот, растяжение и сжатие) какой-либо геометрической фигуры.

Все варианты, естественно, используют компонент таймер Timer, при помощи которого задаются интервалы времени изменения положения объекта.

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

Эту систему можно использовать как справочную систему, из которой можно брать отдельные блоки программ и вставлять в разрабатываемое сложное приложение со сложными эффектами анимации.

Глава 45. Варианты часов с цифровой индикацией, индикаторами прогресса и датой

Листинг 45.1. Метод для вывода короткого времени, без секунд.

private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e)

{

statusBarPanel1->Text = System::DateTime::Now.ToShortTimeString();

}

Для вывода короткой даты (одними цифрами) при помощи метода ToShortDateString дважды щелкаем вторую кнопку Start на Form3 в режиме редактирования (рис. 45.4). Появляется файл Form3.h с шаблоном, который после записи одной строки нашего кода принимает следующий вид.

Листинг 45.2. Метод для вывода короткой даты.

private: System::Void button6_Click(System::Object^ sender, System::EventArgs^ e)

{

statusBarPanel2->Text = System::DateTime::Now.ToShortDateString();

}

Тот же самый шаблон для первой кнопки Start после записи одной строки кода (с целью вывода длинного времени с секундами, при помощи метода ToLongTime String) принимает следующий вид.

Листинг 45.3. Метод для вывода длинного времени с секундами.

private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e)

{

statusBarPanel1->Text = System::DateTime::Now.ToLongTimeString ();

}

Тот же самый шаблон для второй кнопки Start после записи одной строки кода (с целью вывода длинной даты с названием месяца при помощи метода ToLongDate String) принимает следующий вид.

Листинг 45.4. Метод для вывода длинной даты.

private: System::Void button5_Click(System::Object^ sender,

Глава 45. Часы с цифровой индикацией, индикаторами прогресса и датой 239

System::EventArgs^ e)

{

statusBarPanel1->Text = System::DateTime::Now.ToLongDateString();

}

По второму варианту (без двух кнопок Start, но с таймером) из операционной системы компьютера должны выводиться на Form3 значения времени и даты каждые 1000 миллисекунд (или каждую секунду в режиме выполнения программы), которые мы задали в панели Properties для компонента Timer (рис. 45.5). Для этого дважды щелкаем значок timer1 в режиме проектирования (рис. 45.4).

Появляется файл Form3.h с шаблоном, в который можно записать как те же две строки для вывода коротких значений часов и даты из предыдущих методов (листинги 45.1 и 45.2), так и те же две строки кода для вывода длинных значений часов и даты из предыдущих методов (листинги 45.3 и 45.4), как показано на следующих двух листингах.

Листинг 45.5. Метод для вывода коротких значений часов и даты.

private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)

{

statusBarPanel1->Text = System::DateTime::Now.ToShortTimeString();

statusBarPanel2->Text = System::DateTime::Now.ToShortDateString();

}

Листинг 45.6. Метод для вывода длинных значений часов и даты.

private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)

{

statusBarPanel1->Text = System::DateTime::Now.ToLongTimeString();

statusBarPanel2->Text = System::DateTime::Now.ToLongDateString();

}

Листинг 45.7. Код для вывода времени и даты по второму варианту.

label1->Text = System::DateTime::Now.ToLongTimeString(); label2->Text = System::DateTime::Now.ToLongDateString();

В режиме выполнения на Form3 мы увидим время и дату в label1 и label2.

Соседние файлы в предмете Программирование на C++