Начинаем сначала машина сама не срывается со старта, несмотря на работающий мотор. Оператор Клавиатура_сработала = True нужен для того, чтобы запустить счетчик времени
If Клавиатура_сработала Then Время = Время + 1
в процедуре Отображаем_информацию).
Итак, при нажатии нужных клавиш меняются значения нужных переменных. Но дела никакого не происходит. О деле чуть позже, а сейчас давайте подумаем, как сделать так, чтобы автомобиль глядел в ту же сторону, куда он едет. Есть всего 4 направления движения, значит и 4 ориентации автомобиля. Нужно всего лишь взять 4 картинки автомобиля с разной ориентацией и вовремя их менять. Откуда взять картинки? Нарисовать одну в графическом редакторе, а там ее легко поворачивать в нужном направлении и сохраняться. Сохранитесь в 4 файлах. Если вы не хотите рисовать, возьмите из папки с иконками Visual Basic, о которой я уже говорил, 4 иконки в виде стрелок, направленных в разные стороны. Вот вам и автомобиль.
Затем поместите на форму 4 объекта Image, дайте им имена Image_вверх, Image_вниз, Image_налево, Image_направо и придайте им соответствующие картинки. Чтобы эти объекты не мозолили глаза, сделайте их невидимыми. Вся механика будет заключаться в том, что когда вы нажимаете на клавиатуре стрелку вверх, должен выполняться оператор
Image_авто. Picture = Image_вверх. Picture
а когда вниз — то оператор
Image_авто. Picture = Image_вниз. Picture
И так далее.
Теперь можно разбираться в тексте процедур.
Мы с вами чуть выше определили четыре вещи, которые должен проделать автомобиль на каждом импульсе таймера. Посмотрите в процедуру Timer1_Timer и найдите там обращения к соответствующим процедурам. Из них нас сейчас интересует процедура Выбираем_куда_ехать_и_делаем_шаг. Именно она задает направление движения. Загляните в нее. Ее дело — чувствовать одно из 4 значений переменной Руль и запускать соответствующую из 4 процедур. Каждая из этих процедур делает две вещи: поворачивает машину в нужном направлении и меняет в этом направлении ее координату. Само же изображение автомобиля прыгнет на указанную координату чуть позже — во время выполнения процедуры Показываем_автомобиль.
Теперь посмотрим, как регулируется скорость. Прежде всего, при нажатии кнопки Начинаем сначала скорость устанавливается в ноль процедурой Ставим_машину_на_старт. В процессе гонки скорость регулируется процедурой Изменяем_скорость. Действие ее полностью определяется значением переменной Педаль. Если это газ, то на данном такте таймера скорость возрастет на 5. Если тормоз — упадет на 10 (потому что тормоз обычно действует сильнее газа). Как видите, значение переменной Педаль в конце процедуры принудительно приравнивается никакой педали. Это значит, что на следующем такте таймера скорость не изменится. Чтобы она изменилась, нам нужно еще раз нажать на клавишу газа или тормоза. Обычно поступают по-другому — просто удерживают клавишу нажатой, при этом событие KeyDown возникает несколько раз в секунду и скорость меняется достаточно быстро. Это соответствует механике реального автомобиля — чтобы набирать скорость, нужно непрерывно держать нажатой педаль газа, а чтобы тормозить — тормоза.
Процедура Отображаем_информацию заботится о том, чтобы на каждом такте в текстовых полях Спидометр, txtПуть и txtBpeмя были правильные цифры. В нашем проекте переменная Скорость только называется скоростью, а на самом деле это расстояние, на которое перемещается машина на одном такте таймера. Поэтому для вычисления суммарного пути, пройденного автомобилем, вполне уместен оператор Путь = Путь + Скорость. Переменная Время тоже является не временем в секундах, а количеством тактов таймера, прошедших со старта.
Теперь о процедуре Определяем_где_мы. Ее задача — задать реакцию автомобиля на три ситуации: попадание на газон, на финиш и на полосу ограждения. Метод, при помощи которого автомобиль определяет, где он, самый простой — Point. Его мы разобрали в 0. Поскольку газон я рисовал сиреневым (vbMagenta), финиш — синим, а ограждение — красным, то метод Point выдает на них разные результаты. Оператор Select эти результаты анализирует и задает реакцию автомобиля. Как видите, на сиреневое компьютер реагирует только установкой скорости = 15, на два других цвета он выдает сообщение в текстовое поле Сообщение, выключает мотор и устанавливает переменную Приехали, чтобы компьютер ее тут же проанализировал (см. процедуру таймера) и вышел из процедуры таймера, так как, когда приехали, делать, естественно, больше нечего.
В процедуре Ставим_машину_на_старт вы вполне сможете разобраться по комментариям самостоятельно.
Ну вот, кажется, и все пояснения.
Текст программы
Dim х As Integer 'Горизонтальная координата автомобиля
Dim у As Integer 'Вертикальная координата автомобиля
Dim Х_старта As Integer 'Координаты старта и финиша
Dim У_старта As Integer
Dim Х_финиша As Integer Dim У_финиша As Integer
Dim Размер_старта As Integer 'Старт — квадрат, это сторона квадрата
Dim Размер_финиша As Integer 'Финиш — квадрат, это сторона квадрата
Dim Число_газонов As Integer 'Каждый газон — это случайный прямоугольник в случайном месте
Dim Максимальный_размер_гаpона As Integer
Dim Размер_поля As Integer 'Поле — квадрат, это сторона квадрата
Dim Отступ_поля_от_края_формы As Integer 'Имеется в виду отступ слева и сверху
Dim Путь As Long 'Путь автомобиля с момента старта (в твипах)
Dim Время As Integer 'Время измеряется количеством импульсов таймера с момента щелчка по кнопке начала
Dim Скорость As Integer 'Скорость — это не скорость, а расстояние. Она численно равна шагу автомобиля на каждом такте таймера
Dim Пороговая_скорость As Integer 'Скорость, выше которой не работает руль
Dim Цвет_под_автомобилем As Long 'Нужен чтобы знать, где находится автомобиль — на газоне, на финише, врезался в ограждение
Private Enum типРуль
вверх
влево
вниз
вправо
End Enum
Dim Руль As типРуль
Private Enum типПедаль
тормоз
газ
ни_та_ни_эта
End Enum
Dim Педаль As типПедаль
Dim Приехали As Boolean 'Приехали = True, когда приехали на финиш или врезались в ограждение
Dim Клавиатура_сработала As Boolean 'Чтобы секундомер судьи запускался автоматически, когда мы стартуем, не раньше
Private Sub Form_Load()
Timer1.Enabled = False 'Нечего мотору зря работать до начала гонки
Randomize 'Нам придется рисовать случайные газоны
WindowState = 2 'Окно игры распахнуто на весь экран
BackColor = vbWhite 'Асфальт белый
'Задаем и вычисляем размеры элементов поля (все числа подбирайте на опыте):
Отступ_поля_от_края_формы = 500
ScaleLeft = — Отступ_поля_от_края_формы 'Смещаем для удобства начало
системы координат в левый верхний угол поля
ScaleTop = — Отступ_поля_от_края_формы
Размер_поля = Screen.Height — 2 * Отступ_поля_от_края_формы 'Отступ от края