Таймер и моделирование

Теперь о роли таймера в компьютерном конструировании реальных механизмов. Заглянем-ка еще раз в процедуру таймера часов:

Private Sub Таймер_часов_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Таймер_часов.Tick

Dim Время_на_часах As String

Время_на_часах = Format(Now, "HH:mm:ss")

Циферблат_часов.Text = Время_на_часах

If Время_на_часах = "00:00:00" Then Смена_даты_и_дня_недели()

If Будильник_установлен And Время_на_часах = Циферблат_будильника.Text Then Включить_звонок()

End Sub

Вы видите, что эта процедура является главным мотором, приводящим в движение весь механизм часов с будильником, главным штабом, планирующим всю их работу. Таймер, как сердце, несколько раз в секунду посылает импульсы, каждый из которых заставляет выполнится эту процедуру. А что за операторы составляют тело процедуры? Это как раз главные операторы проекта, которые, выполняясь, в свою очередь управляют выполнением вспомогательных процедур Смена_даты_и_дня_недели и Включить_звонок. За один импульс таймера механизм совершает весь цикл своего функционирования с начала до конца и выполняет всю работу, которую положено выполнить: время на часах обновлено; если подошел момент, то именно на этом импульсе заменены дата и день недели; и если подошел момент, то именно на этом же импульсе отдан приказ на включение звонка будильника. На следующем импульсе все повторяется. И так беспрерывно, бесконечно.

Этот принцип применения таймера подойдет для компьютерного конструирования бесчисленного множества других механизмов и аппаратов: холодильника, синтезатора, автоматической метеостанции, беспилотного космического аппарата и пр. и пр. Нужно только знать принцип их работы – и вы сможете создать проект, «вживую» показывающий их деятельность. Это называется моделированием, а сама программа называется моделью.

Вот мы с вами создали модель будильника, которая настолько хороша, что работает не хуже оригинала. Однако, мы не копировали работу реальных шестеренок из бабушкиных ходиков, нам это было не нужно. Таким образом, надо понимать, что мы создали модель только внешнего, а не внутреннего поведения механического будильника. Внутреннее поведение у нашего будильника совсем другое, мы попросту брали готовое время у Windows, и все. Чтобы смоделировать внутреннюю работу реальных механических часов с учетом движения и зацепления каждой шестеренки, нужен гораздо более сложный проект. Спрашивается, кому он нужен? Наверное, тем, кто конструирует часы для любителей старины.

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

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

Задание 81.

«Время в разных странах».Это задание – на любителя. Его делать не нужно, если вы собираетесь выполнить следующее Задание 97 «Шахматные часы».

Усовершенствуйте часы. Пусть они по вашему желанию показывают время в любом из нескольких десятков городов мира. Пользователю достаточно ввести название города в текстовое поле. Для программирования вам нужно самим знать поясное время в других городах. Для этого можете сделать двойной щелчок мышкой по индикатору времени на панели задач Windows и в открывшемся окне загляните в список Time Zone. Основой программы можете сделать большой оператор Select Case. Будильник же не должен обращать внимание на чужое время на циферблате, он все равно должен звонить по нашему местному времени.

Задание 82.

«Шахматные часы». Это задание большое, но его нужно сделать обязательно. Это будет ваш первый опыт создания настоящего проекта.

По шахматным правилам шахматист не может думать над ходом бесконечно. На обдумывание первых 40 ходов ему дается, скажем, суммарное время 2,5 часа. При этом все равно, сколько времени он обдумывает каждый ход. Таким образом, партия, дошедшая до 41 хода, не может продолжаться дольше 5 часов. На следующие ходы тоже отводится какой-то лимит времени. Чтобы шахматист мог следить за тем, сколько времени осталось на обдумывание ему и противнику, существуют специальные шахматные часы. Они представляют собой единый корпус с двумя циферблатами – счетчиками времени, двумя кнопками и двумя флажками. Перед началом партии шахматистов А и В каждый счетчик показывает 2,5 часа. Пусть шахматисту А выпало начинать. Как только партия начинается, судья запускает счетчик А, который начинает обратный отсчет времени, уменьшая свои показания. Таким образом, в каждый момент партии счетчик показывает, сколько времени осталось шахматисту на обдумывание. Пока работает счетчик А, счетчик В, естественно, стоит. Как только шахматист А сделал ход, он тут же нажимает кнопку А, которая останавливает его счетчик и запускает счетчик В. За обдумывание принимается шахматист В. Сделав ход, он нажимает кнопку В, которая останавливает его счетчик и запускает счетчик А. И так далее. Если шахматист просрочит время, его флажок падает – он проиграл.

Для удобства шахматистов добавьте к часам счетчик ходов.

Анимация

Анимацияозначает придание неподвижному предмету движения. Еще одно значение слова анимация – мультфильм.

Суть анимации

Суть анимации лучше всего объяснять, используя методы рисования.

В начале Глава 8. я объяснил идею создания иллюзии движения картинок по экрану. Там же мы двигали по форме объекты – элементы управления. Попробуем заставить двигаться по экрану не объекты, а нарисованные нами геометрические фигуры. Пусть слева направо должна двигаться окружность. Для этого мы должны сначала нарисовать ее слева и быстро стереть, для чего нарисовать ее на том же месте, но цветом фона. Несмотря на то, что мы окружность быстро стерли, она успеет мелькнуть на экране, и глаз это заметит. Затем нужно нарисовать и стереть такую же окружность чуть правее, затем еще правее и т.д.

Ввиду причин, упомянутых в 13.5.3, откажемся от операторов цикла. Будем использовать таймеры. Создадим проект. Поместим в него таймер. Установим его интервал в 30. Вот программа:

Dim x As Integer = 100 'Координаты окружности

Dim y As Integer = 150

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

Dim Граф As Graphics = Me.CreateGraphics

Dim Черное_перо As Pen = New Pen(Color.Black, 5)

Dim Перо_цвета_фона As Pen = New Pen(Me.BackColor, 5)

Dim i As Integer

Граф.DrawEllipse(Черное_перо, x, y, 20, 20) 'Рисуем окружность

For i = 1 To 5000000 : Next 'Пустой цикл для задания паузы

Граф.DrawEllipse(Перо_цвета_фона, x, y, 20, 20) 'Стираем окружность

x = x + 1 'Перемещаемся немного направо

End Sub

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

Задание 83.

Пусть по экрану движется «вагон» – прямоугольник и два кружочка.

Движем объекты

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

Поместим на форму кнопку, объект PictureBox и таймер. Вот программа:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim Граф As Graphics = PictureBox1.CreateGraphics

Dim Черное_перо As Pen = New Pen(Color.Black, 5)

Граф.DrawEllipse(Черное_перо, 3, 3, 20, 20) 'Рисуем один раз окружность

Timer1.Enabled = True 'Включаем движение

End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

PictureBox1.Left = PictureBox1.Left + 1 'Перемещаем PictureBox немного направо

End Sub

Пояснения: На объекте PictureBox1 по нажатию на кнопку рисуется наша окружность и включается таймер, движущий PictureBox1 направо. Обратите внимание, что в отличие от предыдущей программы окружность движется спокойно, не мерцая. Дело в том, что VB создает иллюзию движения гораздо искуснее, чем это умеем делать мы с вами. А ведь тоже рисует и стирает.

Вместо нарисованной примитивной окружности мы могли бы придать элементу PictureBox1 какую-нибудь картинку или фото (присвоить свойству Image или же нарисовать на поверхности PictureBox1 методом DrawImage).. И тогда бы двигалась вся картинка.

Задание 84.

Нарисуйте в графическом редакторе Paint два самолетика на белом фоне и сохраните их изображения. Придайте форме и двум объектам PictureBox на ней белый цвет. Поместите самолетики на объекты PictureBox. Пусть они летят один за другим справа налево.

Задание 85.

Пусть пять кнопок движутся одновременно в разных направлениях: вправо, влево, вверх, вниз, наискосок.

Отскок от края формы. Заставим какой-нибудь объект двигаться направо, а затем самостоятельно отскочить от правого края формы:

Dim Шаг As Integer = 2

Dim x As Integer = 0

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

Button1.Left = x

x = x + Шаг

If x > Width Then Шаг = -2 'Если объект улетел за правый край формы, то лететь обратно

End Sub

Пояснения: Я написал Width, а не Me.Width, но VB не пожаловался, так как считает, что если «хозяин» свойства не указан, то в данном случае «хозяином» является форма.

Задание 86.

Заставьте объект бесконечно двигаться, отскакивая от правого и левого краев формы.

Задание 87.

«Биллиардный шар». Нарисуйте «биллиардный стол» – большой прямоугольник. Шар под углом летает по столу, отскакивая от его краев по закону отражения (Рис. 13.7). Попав в «лузу» (любой из четырех углов стола), он останавливается. Объектом здесь удобно взять маленький PictureBox с загруженной иконкой в виде шарика (подходящие иконки есть в папке VS).

Таймер и моделирование - student2.ru

Рис. 13.7

Указание: В переводе на компьютерный язык слова «по закону отражения» означают вот что. Обозначим dx шаг по горизонтали, dy – по вертикали. Если они оба отличаются от нуля, шарик летит наискосок Удаpившись о левый или пpавый боpт, шаpик меняет гоpизонтальную составляющую скоpости на пpотивоположную: dx = -dx. Аналогично, удаpившись о верхний или нижний боpт, шаpик меняет вертикальную составляющую скоpости на пpотивоположную: dy = -dy.

Задание 88.

«Часы со стрелками». Если вы в ладах с градусной мерой угла, сделайте часы со стрелками: часовой, минутной, секундной. Задача упростится, если вы выберете в качестве стрелок тоненькие сектора окружностей.

Задание 89.

Изобразите полет камня, брошенного с башни, для Задание 47. Камнем может служить PictureBox с подходящей загруженной иконкой. Необходимо, чтобы время полета равнялось реальному времени полета камня.

Задание 90.

Сделайте игру: Пушка на экране стреляет в цель ядрами. С какого выстрела она поразит противника? Между пушкой и целью расположена небольшая гора. Перед началом игры случайно задается горизонтальная координата цели. Затем рисуется картинка (Рис. 13.8).

Таймер и моделирование - student2.ru

Рис. 13.8

Перед каждым выстрелом компьютер отображает в текстовом поле номер выстрела и запрашивает у человека стартовую скорость ядра v и угол a наклона ствола пушки к земле. Затем летит ядро. Полет ядра подчиняется двум уравнениям: s=v*t*cosa и h=v*t*sina – 9.81*t2/2 (см. предыдущее задание). Считается, что цель поражена, если ядро ее коснулось, не коснувшись горы. Вы можете запрограммировать автоматическое определение попадания в цель. Указание: Для этого нужно в момент, когда ядро при падении пересекло уровень земли, сравнить горизонтальные координаты ядра и цели. Если они достаточно близки, то фиксируйте попадание. Определение прикосновения к горе – чуть более хлопотное занятие, но идея та же.

Наши рекомендации