*****************************************************************************************************************************************

Управление при помощи таймера

Многие программы делают что-то, только когда получают команды. Однако компьютерные игры обычно устроены по-другому. Если герой игры будет стоять и ничего не делать, тут же прибегут враги. Поведением врагов управляет таймер — внутренние часы компьютера. Сейчас мы создадим небольшую программу, важнейшим объектом которой будет системный таймер

Описание игры «Поймай кнопку!»

Мы уже знаем, что в системе Visual Basic есть не только визуальные компоненты, но и невизуальные. Объекты, созданные с их помощью, не видны в окне программы — они работают «за кадром».

Таймер — это еще один невизуальный компонент, который есть в системе Visual Basic. Таймер не создает элемента управления, но это не мешает ему иметь свои события и методы. Он может взаимодействовать с другими объектами программы. Для таймера главное событие — истечение заданного интервала времени.

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

Для оформления окна этой программы нам потребуются три объекта. Главный из них — прыгающая командная кнопка. Еще одна кнопка позволит нам выйти из программы. Объект таймер тоже принадлежит форме. Он влияет на работу программы, но сам в программе не виден, а на форме представляется своим заместителем — значком. Примерный вид окна формы для нашей программы показан на рисунке.

Создаем прыгающую кнопку

Запустите систему Visual Basic и создайте новый проект. Сохраните его в папке Таймер. Проектирование формы начинаем с размещения на ней бегающей кнопки и ее настройки. Выберите на панели компонентов (иногда еще говорят «в палитре ком¬понентов») компонент CommandButton (Командная кнопка) и нарисуйте кнопку в верхнем левом углу формы методом протягивания.

  • Задайте для нее следующие свойства.
  • Caption (Заголовок). Введите надпись, которая будет изображаться на кнопке, например Нажми сюда!
  • TabStop (Доступна по клавише TAB). Это свойство разрешает выбрать данный элемент управления клавишей TAB. В этой игре клавиатурой пользоваться нельзя. Чтобы запретить такое «жульничество», задайте этому свойству значение False (Нет).
  • Visible (Видима). Сначала кнопка должна быть невидима, чтобы пользователь не знал, где она находится. Задайте этому свойству значение False (Нет).

Теперь надо немножко подумать. Наша кнопка должна перемещаться по окну. Конечно, можно выбирать ее координаты совершенно случайно. Но давайте поступим по-другому. Пусть у нас будет девять мест, в которых кнопка может появиться. Представьте себе, что на нашей форме есть девять клеток, внутри которых кнопка может находиться.

Самое трудное — точно подобрать размеры кнопки и клеток, чтобы окно выглядело аккуратным. Зададим для кнопки значение высоты равным 500 — свойство Height (Высота) — и значение ширины равным 800 — свойство Width (Ширина).

Единица измерения, которой задаются размеры кнопок, называется «твипом». Ее придумала компания Microsoft, разработавшая систему программирования Visual Basic. Используется эта единица измерения только в продуктах этой компании. Расстояние между разными положениями кнопки должно быть больше, чем ширина и высота кнопок. Пусть оно составляет по горизонтали 900, а по вертикали 600. Мы не можем сразу же присвоить эти значения каким-то свойствам, но они понадобятся нам при программировании. Пусть в левом верхнем положении расстояние между кнопкой и краями формы составляет 200. Задайте значение 200 для свойств кнопки Left (Слева) и Тор (Сверху). Теперь мы можем подсчитать, какой размер должно иметь окно программы. По горизонтали он составит 200+900+900+800+200=3000. По вертикали это будет 200+600+600+500+200=2100. Щелкните на форме и задайте значение 3000 для свойства формы ScaleWidth (Внутренняя ширина). По вертикали нужен запас — ведь в окне будет еще закрывающая кнопка. Поэтому задайте для свойства ScaleHeight (Внутренняя высота) значение 2800. Чтобы размер окна нельзя было изменить в ходе работы программы, задайте для свойства BorderStyle (Тип границы) значение 1 - Fixed Single (Тонкая фиксированная).

Создаем кнопку для закрытия окна

В этой книге мы обычно пренебрегали созданием необязательных элементов управления, таких, как кнопка для закрытия окна. Мы делали это для того, чтобы программа получалась проще и короче. Но на этот раз мы не можем не сделать эту кнопку. Без нее игра станет совершенно неинтересной. Почему? А вот почему. Представьте себе нашу программу в работе без закрывающей кнопки. В ее окне всегда будет только один видимый элемент — подвижная кнопка. Следовательно, в ходе работы программы она всегда будет активной (в таких случаях говорят, что «она будет иметь фокус ввода»). А когда фокус ввода попадает на командную кнопку, она обводится черной рамкой и ее легко можно нажать клавишей ENTER. Выиграть в такой игре было бы слишком просто — достаточно нажать клавишу ENTER в любой момент.

Чтобы лишить пользователя такой возможности легкой победы, нам нужен дополнительный элемент управления, который заберет фокус ввода себе. Например, им может быть кнопка выхода из программы. Выберите компонент CommandButton (Командная кнопка) на панели компонентов и нарисуйте кнопку в нижней части формы методом протягивания. Задайте для свойства Caption (Заголовок) значение Выход. Кроме того, задайте значение True (Да) для свойства Default (По умолчанию) — тогда фокус ввода всегда будет принадлежать этой кнопке и клавиша ENTER накрепко будет связана только с ней.

  • для свойства Left (Слева) — 1100;
  • для свойства Тор (Сверху) — 2100
  • для свойства Width (Ширина) — 800;
  • для свойства Height (Высота) — 500.

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

Добавляем и настраиваем таймер

Пришло время добавить и настроить таймер. Щелкните на кнопке Timer (Таймер) на панели компонентов. Таймер надо расположить за пределами кнопок. Этот объект отображается на форме в виде значка фиксированного размера. В окне работающей программы его не видно.

Самое важное свойство таймера — Interval (Интервал). Оно указывает, когда в следующий раз таймер должен сработать. Промежуток времени задается в тысячных долях секунды — миллисекундах. Пусть наша кнопка прыгает на новое место каждые полсекунды. Зададим для этого свойства значение 500.

Приступаем к программированию

Попробуйте запустить программу, нажав клавишу F5. В окне программы окажется единственная кнопка с надписью Выход, но и она пока не работает. Пока таймер не запрограммирован, наша прыгающая кнопка не видна Впереди у нас еще много работы. Начнем с того, что запрограммируем прыжки кнопки по полю формы. Такие прыжки должны происходить по сигналу, поступающему от таймера. Сигнал таймера — это событие Timer — единственное событие, связанное с таймером. Чтобы открыть окно кода и создать заготовку процедуры Timer1_Timer для обработки этого события, дважды щелкните на значке таймера.

Что надо сделать при обработке этого события? Изменить положение кнопки. Пусть все положения кнопки перенуме¬рованы, как показано на рисунке. Нумерация начинается с нуля — в этом случае программа получится проще. Обратите внимание на то, что если к номеру прибавить число 3, то мы оказываемся в следующей строке, а если число 1, то в следующем столбце.

Это позволяет вычислить положение кнопки для позиции с заданным номером так:
Command1.Тор = 200 + 600 * (i \ 3) Command1.Left = 200 + 900 * (i Mod 3)
Здесь знак «\» — это оператор целочисленного деления. Наверное, вы с таким действием в школе никогда не сталкивались. Оно отличается от обычного действия деления («/») тем, что если частное получается дробным, то дробная часть отбрасывается. Вот несколько примеров:
8/3 = 2,66666
8 \ 3 = 2 9/3 = 3
9 \ 3 = 3
Оператор Mod, скорее всего, вам тоже не знаком. Он вычисляет остаток от деления одного числа на другое. Вот несколько примеров:
6 Mod 3 = 0
7 Mod 3 = 1
8 Mod 3 = 2
9 Mod 3 = 0
Переменная i содержит номер клетки. С помощью умножения и сложения мы переходим от номера клетки к положению кнопки на форме. Значение переменной i надо выбрать случайным образом. Это надо сделать до написанных выше операторов. Кроме того, надо сделать кнопку видимой. Для этого напишем еще два оператора.
i = Int(9 * Rnd)
Commandl.Visible = True
Теперь процедура обработки событий таймера готова. В целом она выглядит так:
Private Sub Timerl_Timer()
i = lnt(9 * Rnd)
Commandl.Visible = True Commandl.Top = 200 + 600 * (i \ 3)
Commandl.Left = 200 + 900 * (i Mod 3)
End Sub
Программируем прыгающую кнопку
В окне кода выберите в раскрывающемся списке слева объект Command 1. Система Visual Basic создаст процедуру Command 1_Click для обработки щелчка на прыгающей кнопке. Если такой щелчок произошел, значит, игра закончилась победой. Чтобы сообщить об этом, изменим надпись на кнопке. Кроме того, отключим ее, чтобы на ней больше нельзя было щелкать. Это можно сделать так:
Private Sub Commandl_Click()
Commandl.Caption = "Готово!
Commandl.Enabled = False
End Sub
Этого достаточно? Нет. Таймер продолжает работать, а значит, не более чем через полсекунды кнопка опять исчезнет с экрана. Поэтому нам надо таймер отключить. Это можно сделать, изменив свойство Enabled (Включен), которое показывает, включен ли таймер:
Timerl.Enabled = False
Последние штрихи

Программа уже почти готова, остались последние штрихи. Во-первых, мы еще не запрограммировали кнопку Выход. Дважды щелкните на ней и впишите в текст созданной процедуры единственный оператор:End

Во-вторых, надо сделать так, чтобы случайные числа не повторялись. Для этого надо создать процедуру обработки загрузки формы Form_Load. Добавьте в нее опера¬тор:Randomizе Тimer

Подведем итоги
Все, наша программа готова. Это уже не такая маленькая программа, как раньше. В ней участвуют четыре подпрограммы. Программисту очень полезно время от времени просматривать свои процедуры и вспоминать, что же они делают. Это особенно важно, когда в про¬грамме встречаются не четыре процедуры, как у нас, а сотни. А теперь посмотрим текст всей программы в целом.
Private Sub Commandl_Click()
Commandl.Enabled = False
Commandl.Enabled = "Готово!"
Timerl.Enabled = False
End Sub
Private Sub Command2_Click()
End
End Sub
Private Sub Form_Load()
Randomize Timer
End Sub
Private Sub Timerl_Timer()
i = Int(9 * Rnd)
Commandl. Visible = True
Commandl.Top = 200 + 600 * (i \ 3)
Commandl.Left = 2 00 + 900 * (i Mod 3)
End Sub

Запустите программу, нажав клавишу F5. Она должна работать именно так, как мы задумали. Закройте окно программы и повторите запуск еще раз. Убедитесь, что путь прыгающей кнопки изменился. Кстати, полсекунды, отведенные нами на щелчок, — это короткий срок. Далеко не каждому удастся догнать кнопку за это время. В этом случае игроку может помочь то, что кнопка иногда задерживается на одном месте. Такое случается, когда наш генератор случайных чисел, основанный на функции Rnd, выдает два или более раз подряд одно и то же число.

Мы пока не предприняли никаких мер, чтобы избежать совпадения старого и нового положений кнопки, но сделать это можно. Просто мы еще знакомы не со всеми операторами Visual Basic и не научили программу «думать».

Кроме того, очень хитрый игрок может не догонять кнопку, а ждать, пока она сама придет туда, куда он поместил указатель мыши. С этим тоже можно побороться, но тогда программа будет намного сложнее. Впрочем, компьютерные игры — это одни из самых сложных программ. Программист должен быть изобре¬тательнее самого хитрого игрока.

Домашнее задание

Если у вас есть младший братишка или сестренка, которым непросто догнать прыгающую кнопку, попробуйте изменить игру так, чтобы они могли сами настраивать ее скорость. Для этого можно создать еще две командные кнопки: Медленнее и Быстрее. Щелчок на одной из них будет увеличивать значение свойства Timerl.Interval, например на 100 миллисекунд, а на другой — уменьшать его, например в два раза.

Удивляйте детей!

Хостинг от uCoz