Книга Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 4: Программирование на Visual Basic искусственного интеллекта - читать онлайн бесплатно, автор Валерий Алексеевич Жарков. Cтраница 3
bannerbanner
Вы не авторизовались
Войти
Зарегистрироваться
Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 4: Программирование на Visual Basic искусственного интеллекта
Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 4: Программирование на Visual Basic искусственного интеллекта
Добавить В библиотекуАвторизуйтесь, чтобы добавить
Оценить:

Рейтинг: 0

Добавить отзывДобавить цитату

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

Dim OffOn As Boolean '= False по умолчанию.

Private Sub Button2_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button2.Click

'Задаём чередование остановки и возобновления анимации

'после каждого щелчка кнопки Button:

If (OffOn = False) Then

'Останавливаем анимацию:

Timer1.Enabled = False

'Изменяем значение OffOn на противоположное:

OffOn = True

Else

'Возобновляем анимацию:

Timer1.Enabled = True

'Изменяем значение OffOn на противоположное:

OffOn = False

End If

End Sub

Этот листинг можно записать короче:

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

'Объявляем булеву переменную OffOn и задаём ей значение True:

Dim OffOn As Boolean = True

Private Sub Button2_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button2.Click

OffOn = Not OffOn

Timer1.Enabled = OffOn

End Sub

Для проверки реализации алгоритма запускаем программу, например, так: Ctrl+F5. В ответ Visual Basic выполняет программу и выводит форму в режиме выполнения.

На этой форме с заданной нами частотой в 500 миллисекунд (или 0,5 секунды) заголовок “Калькулятор (Calculator)” сменяется на “Калькулятор с анимацией (Calculator with animation)” (рис. 2.11), и таким образом создаётся эффект анимации.

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

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



Рис. 2.12.

2.9. Методика подачи звукового сигнала

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

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

Dim N As Integer = 10

а в самой процедуре организовываем цикл по статической переменной i:

Static i As Integer

i = i + 1

If i <= N Then

Beep()

End If

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

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

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

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

Глава 3. Методика разработки приложений на нескольких формах и передачи данных с одной формы на другую

3.1. Алгоритм приложения и проектирование первой формы

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

Алгоритм этого примера сформулируем так: на первой (главной) форме: в первое окно вводим первый сомножитель; во второе окно вводим второй сомножитель; щёлкаем по кнопке со знаком равенства; на появившейся второй форме (с пустыми тремя окнами) щёлкаем кнопку OK, после чего во всех трёх окнах мы увидим числа. Проверяем (контролируем) правильность вывода программой двух сомножителей в первые два окна второй формы (эти значения мы просто передадим с первой формы и подробно объясним, как это делается); анализируем результат умножения, который мы увидим в третьем окне.

Кратко, чтобы не повторяться (более подробно приведено выше и в [Литература]), опишем создание проекта для нового приложения-диалога. В VS щёлкаем значок New Project (или выбираем File, New, Project). В панели New Projects в окне Project Types выбираем тип проекта Visual Basic, Windows, в окне Templates проверяем, что выделено (по умолчанию) Windows Forms Application, в окне Name записываем имя проекта, например, Calculator2_2 (первая цифра 2 означает второй вариант калькулятора, а вторая цифра 2 – на двух формах). Щёлкаем OK. В ответ Visual Basic создаёт проект нашего приложения и выводит рабочий стол с формой Form1(аналогично форме в предыдущей главе). По разработанной выше методике осуществляем визуальное проектирование формы (рис. 3.1) и вводим элементы управления (рамку группы GroupBox, окна TextBox, кнопки Button, тексты Label) и компонент таймер (свойства таймера Timer: Enabled – True; значение Interval, например, оставляем по умолчанию, равным 100).



Рис. 3.1. Form1 в режиме выполнения.

3.2. Проектирование следующей формы

Для ввода в проект новой формы, в меню Project выбираем Add Windows Form, в панели Add New Item щёлкаем кнопку Add (или Open). В ответ Visual Basic выводит рабочий стол с новой формой Form2 и добавляет в панель Solution Explorer новый пункт Form2.vb. Аналогично, как первую, проектируем вторую форму (рис. 3.2). По этой схеме можно добавлять и большее количество форм, сколько необходимо для каждого конкретного приложения.



Рис. 3.2. Form2 в режиме выполнения.

3.3. Код программы

Дважды щёлкаем кнопку “=” на форме Form1 в режиме проектирования. Появившийся шаблон (после записи нашего кода) принимает вид следующей процедуры.

Листинг 3.1. Процедура Button1_Click с нашим кодом для первой формы.

Private Sub Button1_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click

Dim A, B As Double

A = Convert.ToDouble(TextBox1.Text)

B = Convert.ToDouble(TextBox2.Text)

Dim myForm2 As New Form2

myForm2.C = A

myForm2.D = B

myForm2.Show()

End Sub

Дважды щёлкаем кнопку OK на Form2. Перед появившимся шаблоном объявляем две открытые глобальные переменные C и D, а внутри этого шаблона записываем наш код, после чего шаблон принимает вид следующей процедуры.

Листинг 3.2. Строка и процедура Button1_Click с нашим кодом для Form2.

Public C, D As Double

Private Sub Button1_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click

Dim F, G As Double

F = C : G = D

TextBox1.Text = F.ToString

TextBox2.Text = G.ToString

TextBox3.Text = (F * G).ToString

End Sub

Таких локальных переменных, как A и B, и, соответственно, глобальных переменных C и D, в общем случае, мы записываем попарно столько, сколько на первой форме имеется окон TextBox, из которых мы будем передавать значения на другую форму. Переменные F, G можно не вводить (мы их ввели для наглядности) и заменить их на C, D. Отметим, что мы разработали несколько вариантов кода для передачи данных с одной формы на другую, но в этой книге приводим только один вариант (листинги 3.1 и 3.2), как наиболее простой. Другие варианты кода даны и подробно объяснены в наших книгах [Литература].

3.4. Методика разработки анимации в виде бегущей строки

На основании разработанной в предыдущей главе методики создания анимационного заголовка формы в данной главе мы разработаем методику создания бегущей строки любого текста, как в заголовке формы, так и внутри какого-либо элемента управления. Эту методику опишем на примерах двух вариантов подвижного заголовка, а именно: бегущий слева – направо заголовок первой формы; бегущий справа – налево заголовок следующей формы. Алгоритм бегущего слева – направо заголовка первой форме формулируем так: начиная с первой буквы, поэтапно появляются буквы заголовка (по одной букве) с заданным нами в панели Properties интервалом времени Interval; после появления всех букв заголовка он исчезает, и цикл поэтапного (побуквенного) вывода заголовка повторяется. Для программной реализации этого алгоритма дважды щёлкаем значок для компонента Timer ниже первой формы в режиме проектирования. Появляется файл Form1.vb с шаблоном метода Timer1_Tick для обработки события Tick, периодически (с заданным интервалом) возбуждаемого объектом (таймером) Timer. Этот автоматически генерируемый шаблон мы уже приводили выше. Здесь мы будем давать лишь наш код, который следует записать в этот шаблон.

Листинг 3.3. Код для бегущего слева – направо заголовка.

'Записываем текст заголовка:

Dim myString As String = "Калькулятор2_2 (Calculator2_2) "

'Объявляем статическую переменную, по умолчанию равную нулю:

Static i As Integer

'Справа – налево появляются буквы заголовка:

Me.Text = myString.Substring(0, i)

i = i + 1

'Организовываем цикл вывода заголовка:

If i = myString.Length Then i = 1

Алгоритм бегущего справа – налево заголовка следующей формы формулируем иначе (чем предыдущий): появляются все буквы заголовка; начиная с последней буквы, поэтапно исчезают буквы заголовка (по одной букве) с заданным нами в панели Properties интервалом времени Interval; после исчезновения последней буквы заголовка снова появляются все буквы заголовка и цикл поэтапного (побуквенного) удаления заголовка повторяется. Дважды щёлкаем значок для компонента Timer ниже формы в режиме проектирования. Появляется файл Form1.vb с шаблоном, в который записываем код:

Листинг 3.4. Код для бегущего справа – налево заголовка.

'Записываем текст заголовка:

Dim myString As String = _

"Калькулятор2_2 (Calculator2_2). Форма2 (Form2) "

'Статическая переменная, равная числу знаков заголовка:

Static i As Integer = myString.Length()

'Слева – направо удаляются буквы заголовка:

Me.Text = myString.Substring(0, i)

i = i – 1

'Организовываем цикл удаления букв заголовка:

If i = -1 Then i = myString.Length()

Аналогично можно запрограммировать бегущую строку внутри какого-либо элемента управления (или нескольких элементов управления), если на листингах 3.3 и 3.4 в строке (Me.Text = myString.Substring(0, i) после оператора (Me.) мы допишем имя этого элемента управления (свойство Name), например, (Button1.) для кнопки.

3.5. Выполнение расчётов

Проверяем в действии созданное нами приложение (проект) в виде программы-калькулятора, например, для вычисления произведения двух чисел:

1. Запускаем программу: Build, Build Selection; Debug, Start Without Debugging.

В ответ Visual Basic выполняет программу и выводит первую форму с пустыми окнами и мигающим курсором в первом окне. Мы видим также бегущий слева – направо заголовок формы.

2. В первое окно вводим первый сомножитель (рис. 3.1).

3. Щёлкаем во втором окне, вводим второй сомножитель и щёлкаем кнопку “=”.

Появляется вторая форма (рис. 3.2) с пустыми окнами. Мы видим также бегущий справа – налево заголовок формы.

4. На второй форме щёлкаем кнопку OK.

В ответ Visual Basic на второй форме показывает (рис. 3.2):

в первом окне – значение первого сомножителя;

во втором окне – значение второго сомножителя;

в третьем окне – результат умножения двух чисел.

После окончания расчётов щёлкаем значок “x” (Close). В ответ Visual Basic закрывает вторую форму, но оставляет открытой первую форму. Мы можем ввести другие значения в окна первой форме и аналогично получить результат умножения других чисел.

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

1. Щёлкаем в окнах первой формы (активизируем её), вводим два (или одно) других числа (например, результат предыдущего расчёта) и щёлкаем кнопку “=”.

Появляется второй вид второй формы с пустыми окнами.

2. Щёлкаем OK и на этой форме получаем результат умножения уже других чисел.

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

После окончания расчётов последовательно щёлкаем значок “x” (Close) на каждой форме, и формы также последовательно (по одной) закрываются.

Таким образом, мы получили решение задач согласно разработанным выше алгоритмам с учётом анимации.

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

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

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

А в данной книге, следуя её названию, а также следуя приведённым в предыдущих главах основам, приступим к разработке двухмерных и трёхмерных игр и приложений на платформах Visual Studio для настольных компьютеров, ноутбуков и планшетов как с DirectX, так и без.

Часть II. Учебная методология программирования игр и приложений с подвижными объектами

Глава 4. Методика анимации и управления подвижными объектами

4.1. Методика добавления объекта в проект

Разработаем общую обучающую методику создания типичной и широко распространённой игры, когда в качестве летающих игровых объектов используются продукты питания, следуя статье с сайта microsoft.com: Rob Miles. Games Programming with Cheese: Part One. Так как эта статья написана по программированию игры на Visual C# для смартфона и, к тому же, при помощи устаревшей версии Visual Studio, то автор данной книги переработал статью для программирования игры на настольном компьютере и, к тому же, на Visual Basic при помощи новейшей версии Visual Studio. Общие требования к программному обеспечению для разработки этой игры приведены выше. Методично и последовательно начнём решать типичные задачи (с подробными объяснениями) по созданию данной базовой учебной игры и всех подобных игр типа аркады (arcade). Первым летающим объектом, используемом в игре, является, например, какой-либо продукт питания, например, маленький кусочек сыра (cheese). Так как на экране должно размещаться большое количество игровых объектов, то размер изображения сыра также должен быть небольшим, например, 25 x 32 пикселей. Если необходимо уменьшить объём файла любого изображения, то можно воспользоваться каким-либо графическим редактором, например, Paint, который поставляется с любой операционной системой Windows.

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

Создаём базовый учебный проект по обычной схеме: в VS в панели New Project в окне Project types выбираем тип проекта Visual Basic, Windows, в окне Templates выделяем шаблон Windows Forms Application, в окне Name записываем (или оставляем по умолчанию) имя проекта, например, Cheese1 и щёлкаем OK. Важно отметить, что, так как, в отличие от приведённой выше статьи, имя этого проекта мы будем определять далее в коде программы, то в окне Name можно записать любое имя. Создаётся проект, появляется форма Form1 (рис. 4.1) в режиме проектирования. Проектируем (или оставляем по умолчанию) форму, как подробно описано в параграфе “Методика проектирования формы”. Например, если мы желаем изменить фон формы с серого на белый, то в панели Properties (для Form1) в свойстве BackColor устанавливаем значение Window.

Добавляем в проект (из отмеченной выше статьи или из Интернета) файл изображения сыра cheese.jpg по стандартной схеме, а именно: в меню Project выбираем Add Existing Item, в этой панели в окне “Files of type” выбираем “All Files”, в центральном окне находим и выделяем имя файла и щёлкаем кнопку Add (или дважды щёлкаем по имени файла).

В панели Solution Explorer мы увидим этот файл (рис. 4.2).

Теперь этот же файл cheese.jpg встраиваем в проект в виде ресурса по разработанной выше схеме, а именно: в панели Solution Explorer выделяем появившееся там имя файла, а в панели Properties (для данного файла) в свойстве Build Action (Действие при построении) вместо заданного по умолчанию значения Content (Содержание) или None выбираем значение Embedded Resource (Встроенный ресурс). Для написания программы, в самом верху файла Form1.vb записываем пространство имён System.Reflection для управления классом Assembly:

Imports System.Reflection 'Для класса Assembly.

В панели Properties (для Form1) на вкладке Events дважды щёлкаем по имени события Paint. Появившийся шаблон метода Form1_Paint после записи нашего кода принимает следующий вид.

Другие варианты вывода изображения, например, на элемент управления PictureBox и после щелчка по какому-либо элементу управления уже приводились в предыдущих книгах.



Рис. 4.1. Форма.





Рис. 4.2. Файл рисунка в SE и Properties.

Листинг 4.1. Метод для построения изображения.

'Объявляем объект класса System.Drawing.Image для продукта:

Dim cheeseImage As Image

'Загружаем в проект файлы изображений и звуков по такой схеме:

'Создаём объект myAssembly класса Assembly и присваиваем ему

'ссылку на исполняемую сборку нашего приложения:

Dim myAssembly As Assembly = Assembly.GetExecutingAssembly()

'Создаём объект myAssemblyName

'класса System.Reflection.AssemblyName и присваиваем ему

'имя сборки, которое состоит из имени проекта,

'Version, Culture, PublicKeyToken:

Dim myAssemblyName As AssemblyName = myAssembly.GetName()

'Из имени сборки при помощи свойства Name

'выделяем имя проекта типа string:

Dim myName_of_project As String = myAssemblyName.Name

Private Sub Form1_Paint(ByVal sender As System.Object, _

ByVal e As System.Windows.Forms.PaintEventArgs) _

Handles MyBase.Paint

'Загружаем в объект класса System.Drawing.Image

'добавленный в проект файл изображения заданного формата

'при помощи потока встроенного ресурса (ResourceStream):

cheeseImage = _

New Bitmap(myAssembly.GetManifestResourceStream( _

myName_of_project + "." + "cheese.JPG"))

'Рисуем изображение на форме Form1:

e.Graphics.DrawImage(cheeseImage, 10, 20)

End Sub

Строим и запускаем программу на выполнение обычным образом:

Build, Build Selection;

Debug, Start Without Debugging.

В ответ VS выводит панель Deploy (с именем проекта), на которой выбираем устройство (Device) типа Windows Mobile 6 Classic (или Professional) Emulator и щёлкаем кнопку Deploy.

Появляется форма Form1 с изображением типа встроенного нами рисунка сыра cheese.jpg (рис. 4.1).

Верхний левый угол изображения по отношению к верхнему левому углу экрана (где находится начало координат) расположен в соответствии с заданными нами координатами в строке кода (e.Graphics.DrawImage(myBitmap, 10, 20)).

4.2. Методика анимации объекта

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

Следующий пример кода создаёт метод updatePositions, который перемещает сыр. На данной стадии проектирования сыр будет только двигаться вправо и вниз (по осям координат “x” и “y”). Таким образом, добавляем в данный (или новый) проект такой код.

Листинг 4.2. Изменение координат продукта.

'Текущая абсцисса объекта:

Dim cx As Integer = 50

'Текущая ордината объекта:

Dim cy As Integer = 100

Private Sub updatePositions()

cx = cx + 1

cy = cy + 1

End Sub

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

В процессе игры, для вызова метода updatePositions через одинаковые промежутки времени, целесообразно использовать таймер. С панели инструментов Toolbox размещаем на форме компонент Timer (Таймер). В панели Properties (для данного компонента Timer) в свойстве Enabled оставляем логическое значение False, а свойству Interval задаём значение 40 (миллисекунд, что соответствует 25 кадрам в секунду по стандарту телевещания России; 1000 миллисекунд равно 1 секунде).

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

Кроме того, таймер не должен быть включённым, пока программа не загрузит изображение. Поэтому в приведённом выше методе Form1_Paint в самом низу следует дописать:

'Включаем таймер:

Timer1.Enabled = True

Окончательно, код в теле метода Form1_Paint должен иметь такой вид.

Листинг 4.3. Метод для рисования изображения.

Private Sub Form1_Paint(ByVal sender As System.Object, _

ByVal e As System.Windows.Forms.PaintEventArgs) _

Handles MyBase.Paint

'Загружаем в объект класса System.Drawing.Image

'добавленный в проект файл изображения заданного формата