Читать книгу Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 1: Программирование на Visual C# искусственного интеллекта - Валерий Алексеевич Карданов, Дарья Андреевна Самсонова, Наталья Сергеевна Кузьмина - Страница 10

Часть I. Краткие основы Visual C#
Глава 2. Методика разработки приложений для выполнения расчётов с эффектами анимации
2.7. Общая методика создания анимации

Оглавление

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

Для создания любой анимации необходимо ввести компонент Timer по схеме:

1. На панели инструментов Toolbox щёлкаем строку Timer (рис. 2.3).

2. Щёлкаем на форме.

Ниже Form1 появляется значок с надписью timer1 (рис. 2.9), который можно захватить мышью и перенести в другое место.

Отметим, что в отличие от элементов управления компоненты располагаются вне формы и поэтому на форме в режиме выполнения не видны.

3. В панели Properties с заголовком timer1:

в свойстве Enabled вместо False выбираем True (рис. 2.10);

в свойстве Interval вместо заданных по умолчанию 100 миллисекунд задаём, например, значение 500 миллисекунд (напомним, что 1000 миллисекунд равны 1 секунде).

Естественно, эти установки можно выполнить не только в панели Properties, но и в программе, например, при помощи следующего кода.


Листинг 2.2. Метод для включения таймера и задания интервала времени.

private void InitializeTimer ()

{

//We turn on the timer:

timer1.Enabled = true;

//We generate the Tick event through each Interval of time:

timer1.Interval = 500;


}



Рис. 2.9. Значок компонента Timer. Рис. 2.10. Панель Properties.


Теперь в режиме выполнения проекта с интервалом в эти 500 миллисекунд (или 0,5 секунды) будет генерироваться запрограммированное нами событие Tick и выполняться при помощи метода timer1_Tick (см. ниже листинг 2.3), а именно, в данной главе будет мигать заголовок формы.

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

Рассмотрим, например, три варианта:


1) анимация выполняется безостановочно столько, сколько выполняется наше приложение, и анимационный объект (текст, кнопка, цвет и т.д.) изменяется за каждый интервал времени Interval;

2) анимация выполняется безостановочно столько, сколько выполняется наше приложение, но анимационный объект изменяется не за каждый интервал времени Interval, а через заданное нами число интервалов N_Interval;

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


Сначала изучим первый вариант, когда анимация выполняется безостановочно за каждый интервал времени Interval. Для этого дважды щёлкаем значок timer1 (рис. 2.8) в режиме проектирования (или в панели Properties на вкладке Events дважды щёлкаем по имени единственного события Tick).

Появляется файл Form1.cs с автоматически сгенерированным шаблоном метода, выше которого объявляем булеву переменную, а в шаблон записываем такой код.


Листинг 2.3. Код для создания анимации. Вариант 1.


//We declare the Boolean myText variable and appropriate it

//«false» (by default too «false»):

bool myText = false;


private void timer1_Tick (object sender, EventArgs e)

{

//We set the alternation of «Calculator» and

//" Calculator with animation»:

if (myText == false)

{

this. Text = " Calculator»;

//We change the myText value to opposite:

myText = true; //or so: myText =! myText;

}

else

{

this. Text = " Calculator with animation»;

//We change the myText value to opposite:

myText = false; //or so: myText =! myText;

}

}


В этом коде использовано правило переноса текста с одной строки на другую.

Теперь изучим второй вариант, когда анимация выполняется безостановочно столько, сколько выполняется наше приложение, но анимационный объект изменяется не за каждый интервал времени Interval, а через заданное нами число интервалов N_Interval. Для этого в файле Form1.cs выше того же (что и в предыдущем варианте) автоматически сгенерированного шаблона метода объявляем переменные, а в шаблон записываем код, как показано на следующем листинге.


Листинг 2.4. Код для создания анимации. Вариант 2.


//We declare the counter of number of intervals

//and set its initial value:

private int counter = 0; //by default too it is equal to 0.

//We declare and set the number N_Interval of intervals,

//after which one text is replaced by another:

private int N_Interval = 3;


private void timer1_Tick (object sender, EventArgs e)

{

//We check, value of the counter

//equally or yet is not present to number N_Interval of

//intervals,

//after which one text is replaced by another:

if (counter> = N_Interval)

{

//If value of the counter collected and is equal

//N_Interval, we output other text:

this. Text = «Calculator»;

//We nullify the value of the counter again:

counter = 0;

}

else

{

//If value of the counter did not collect yet

//and N_Interval is not equal,

//that we output the first text:

this. Text = «Calculator with animation»;

//We increase value of the counter on 1:

counter = counter +1;

}

}


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


Листинг 2.5. Код для создания анимации. Вариант 3.


//We declare the counter of number of intervals

//and set its initial value:

private int counter = 0;

//We declare and set the number N_Interval of intervals,

//after which one text is replaced by another:

private int N_Interval = 3;

//We declare and nullify the i_Interval_Stop counter,

//which calculates the number of intervals

//to an animation stop:

private int i_Interval_Stop = 0;

//We declare and set the number N_Interval_Stop of intervals,

//on reaching which animation stops:

private int N_Interval_Stop = 10;


private void timer1_Tick (object sender, EventArgs e)

{

//Value of the i_Interval_Stop counter,

//which calculates the number of intervals

//to an animation stop, we increase on 1:

i_Interval_Stop = i_Interval_Stop +1;

//We check the number i_Interval_Stop of intervals,

//on reaching which animation stops:

if (i_Interval_Stop> = N_Interval_Stop)

timer1.Enabled = false;

//We check, value of the counter

//equally or yet is not present to number N_Interval of

//intervals,

//after which one text is replaced by another:

if (counter> = N_Interval)

{

//If value of the counter collected and is equal

//N_Interval, we output other text:

this. Text = «Calculator»;

//We nullify value of the counter again:

counter = 0;

}

else

{

//If value of the counter did not collect yet

//and N_Interval is not equal,

//that we output the first text:

this. Text = «Calculator with animation»;

//We increase value of the counter on 1:

counter = counter +1;

}

}


Так как здесь мы впервые применили метод timer1_Tick, а далее постоянно будем его применять, то дадим краткие пояснения.


Автоматически сгенерированный заголовок метода


private void timer1_Tick (object sender, EventArgs e)


говорит нам о том, что метод timer1_Tick обрабатывает (Handles) событие Tick, периодически (с заданным интервалом при помощи свойства Interval) возбуждаемое объектом (таймером) timer1. В строке (bool myText = false;) мы объявляем булеву глобальную переменную myText выше метода timer1_Tick. Если бы переменную myText мы задали в виде локальной переменной внутри метода timer1_Tick, то при каждом новом вызове (с заданным интервалом) этого метода timer1_Tick значение переменной myText оставалось бы неизменным, и анимации не получилось бы.

По какому-либо одному варианту кода, например, по первому варианту строим программу и запускаем на выполнение обычным образом: Build, Build Selection; Debug, Start Without Debugging.

В ответ Visual C# выполняет программу и на рабочий стол выводит форму в режиме выполнения. На этой форме с заданной нами частотой в 500 миллисекунд (или 0,5 секунды) заголовок «Калькулятор (Calculator) ” сменяется на «Калькулятор с анимацией (Calculator with animation) ” (рис. 2.10), и таким образом создаётся эффект анимации.


Рис. 2.10. Форма с анимационным заголовком.


Если на листингах 2.3 – 2.5 вместо слова «Калькулятор (Calculator)» записать оператор «» (т.е. удалить слово «Калькулятор (Calculator)»), то будет появляться и исчезать только второй заголовок формы «Калькулятор с анимацией (Calculator with animation)», и этот заголовок будет только мигать (без замены текста) с заданной частотой. Далее на этом калькуляторе можно выполнять описанные выше расчёты (рис. 2.10).

Аналогично создаётся анимация по второму варианту (листинг 2.4) и третьему варианту (листинг 2.5); каждый вариант имеет свои особенности. И читатель может выбрать наиболее понравившийся вариант анимации. Мы же в дальнейшем будем применять, в основном, первый вариант, как наиболее простой.

Следовательно, мы закончили разработку методики создания трёх вариантов анимации на примере анимационного заголовка формы. Подчеркнем, что мы разработали именно общую методику создания анимации, так как если в программах на листингах 2.3 – 2.5 вместо ключевого слова this записать значение свойства Name для какого-нибудь элемента управления (label1, button1 и т.д.), то мы получим эффект анимации для текста на этом элементе управления.


2.8. Методика приостановки и возобновления анимации


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


Листинг 2.6. Строка кода, останавливающая анимацию.


timer1.Enabled = false;


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

Чтобы возобновить анимацию, мы должны в обработчик события записать другую строку кода:


Листинг 2.7. Строка кода, возобновляющая анимацию.


timer1.Enabled = true;


Теперь объединим эти две последние строки кода в обработчике события с целью приостановки и возобновления анимации после каждого щелчка, например, кнопки. Для этого в режиме проектирования Form1 стандартно (как описано выше) вводим новую кнопку Button, в свойстве Text записываем &Stop/Start Animation и дважды щёлкаем по этой кнопке (или в панели Properties для этой кнопки на вкладке Events дважды щёлкаем по имени события Click). Появляется файл Form1.cs с автоматически сгенерированным шаблоном метода, выше которого объявляем булеву переменную, а в шаблон записываем код, как показано на следующем листинге:


Листинг 2.8. Код для приостановки и возобновления анимации.


//We declare the Boolean OffOn variable and set it «false»:

bool OffOn = false;


private void button2_Click (object sender, EventArgs e)

{

//We set alternation of a stop and resuming of animation

//after each click of the button2 button:

if (OffOn == false)

{

//We stop the animation:

timer1.Enabled = false;

//We change the OffOn value to opposite:

OffOn = true; //or so: OffOn =! OffOn;

}

else

{

//We resume the animation:

timer1.Enabled = true;

//We change OffOn value to opposite:

OffOn = false; //or so: OffOn =! OffOn;

}

}


Для проверки этого кода по первому варианту (листинг 2.3) запускаем программу, например, так: Ctrl+F5. В ответ Visual C# выполняет программу и на рабочий стол выводит форму в режиме выполнения. На этой форме с заданной нами частотой в 500 миллисекунд (или 0,5 секунды) заголовок «Калькулятор (Calculator) ” сменяется на «Калькулятор с анимацией (Calculator with animation) ” (рис. 2.11), и таким образом создаётся эффект анимации.


Рис. 2.11. Анимация прекращается и возобновляется после щелчка кнопки Stop/Start Animation.


Анимация прекращается и возобновляется поочередно после каждого щелчка кнопки (рис. 2.11). Так как в свойстве Text мы записали &Stop/Start Animation с символом &, то первая буква S подчёркнута и, следовательно, эту кнопку можно нажать не только мышью, но и комбинацией клавиш Alt+s.

Если мы желаем, чтобы анимация прекращалась и возобновлялась после каждого щелчка по данной форме, то в панели Properties для этой формы на вкладке Events дважды щёлкаем по имени события Click и в появившийся шаблон метода записываем код, подобный коду на листинге 2.8.

Аналогично можно разработать другие варианты анимации, а также варианты приостановки и возобновления анимации и мультипликации, как показано в наших предыдущих книгах, например, [9] или с сайта ZharkovPress.com.


2.9. Общая методика использования методов из других платформ на основе динамически подключаемых библиотек


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

Для создания ссылки, например, на Visual Basic выполняем такие шаги.

1. В меню Project выбираем Add Reference (или в панели Solution Explorer делаем правый щелчок на имени проекта и в появившемся контекстном меню выбираем Add Reference).

Мы увидим панель Add Reference (рис. 2.12).

2. В панели Add Reference на вкладке (.NET) выделяем динамически подключаемую библиотеку (dynamic link library), например, Microsoft.VisualBasic и щёлкаем кнопку OK.

Эта ссылка добавляется в список ссылок в панели Solution Explorer (рис. 2.13).

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



Рис. 2.12. Выбираем Microsoft.VisualBasic. Рис. 2.13. Панель Solution Explorer.


2.10. Методика использования методов из других платформ на примере подачи звукового сигнала


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

В одной из наших предыдущих книг мы уже писали, что подача звукового сигнала в Visual Basic основана на том, что в тело функции для обработки какого-либо события в любом приложении следует записать стандартную функцию Beep (). Если в комплексе Visual Basic мы запишем Beep () в функцию для обработки события Tick таймера, то звуковой сигнал будет периодически создаваться согласно генерируемому событию Tick с заданным нами интервалом времени.

Если мы запишем Beep () в функцию для обработки, например, события Tick таймера в комплексе Visual C#, то выйдет сообщение об ошибке, что в Visual C# такой функции нет.

Согласно приведённой в предыдущем параграфе методике использования в нашем приложении метода (функции) из любого другого комплекса, создаём ссылку на Visual Basic. Когда в шаблон функции для обработки, например, события Tick таймера в Visual C# мы запишем (после пространства имён Microsoft) оператор в виде точки (.), то увидим подсказку из списка пространств имен, которые мы можем применить в данном приложении (рис. 2.14).


Рис. 2.14. Пространства имён, которые можно применить в приложении VC#.

Дважды щёлкаем по имени Visual Basic, тем самым вставляя это имя в код (Microsoft.VisualBasic).

Когда далее после имен Microsoft.VisualBasic мы запишем тот же оператор (.), то увидим подсказку из списка классов пространства имён VisualBasic, которые мы можем применить в данном приложении (рис. 2.15). Отметим, что если бы ранее мы не создали ссылку на динамически подключаемую библиотеку (dynamic link library) Microsoft.VisualBasic, то сейчас мы бы не увидели этого списка классов. Дважды щёлкаем по имени класса Interaction, тем самым вставляя это имя в код:


Microsoft.VisualBasic.Interaction


Рис. 2.15. Список классов, которые можно применить в приложении.


Когда далее после имен Microsoft.VisualBasic.Interaction мы запишем оператор (.), то увидим подсказку в виде списка методов (процедур и функций) Visual Basic из класса Interaction, которые мы можем применить в данном приложении (рис. 2.16). Дважды щёлкаем по имени функции Beep (), тем самым вставляя это имя в код (Microsoft.VisualBasic.Interaction.Beep ()).

Таким образом, мы закончили запись в шаблон метода для обработки, например, события Tick таймера в Visual C# одной строки кода с методом Beep ():


Microsoft.VisualBasic.Interaction.Beep ();


Этот звуковой сигнал Beep будет периодически создаваться согласно генерируемому событию Tick с заданным нами интервалом времени Interval.


Рис. 2.16. Список методов, которые можно применить в приложении.


Если мы хотим ограничить число звуковых сигналов величиной N_Beep, то выше шаблона метода объявляем и инициализируем (например, 10) эту переменную N_Beep:


//We declare the counter of number of intervals

//and set its initial value:

int i = 0;

//We declare and set the number N_Beepof of intervals,

//after which a giving of a sound signal will stop:

int N_Beep = 10;


Далее в шаблоне метода организовываем цикл по переменной i:


i = i +1;

if (i <= N_Beep)

Microsoft.VisualBasic.Interaction.Beep ();


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

Также далее кратко, а в наших предыдущих книгах (например, [9]) подробно мы разработаем методику дополнения любого приложения говорящими мультипликационными персонажами, которыми можно управлять при помощи щелчков клавиш и кнопок и голосовых команд в микрофон.

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

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

Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 1: Программирование на Visual C# искусственного интеллекта

Подняться наверх