Процесс игры таков. Вы нажимаете на кнопку Начинаем сначала. На форме рисуется квадратное поле для гонки со случайно расположенными газонами. Нажатием на клавишу пробела вы даете газ и машина со старта набирает скорость. Ваша цель — любым путем побыстрее добраться до финиша. На белом асфальте вы можете газовать до любой скорости. Если же ненароком попадете на газон, то на газоне ваша скорость будет очень мала (я выбрал 15). Поэтому имеет смысл по газонам ездить пореже. Направление движения может быть только горизонтальное и вертикальное, наискосок машина не движется. Выбор направления (руль) — это клавиши со стрелками. Тормоз — клавиша В (английская). Тормозить надо по той причине, что на слишком большой скорости руль отказывает (это не потому, что проект плохой, а потому что я так придумал). В ограждение врезаться нельзя — катастрофа. Когда приедете на финиш, посмотрите на счетчик времени — это ваш результат. Снова нажимаете на кнопку Начинаем сначала. Теперь расположение газонов будет другим. Сажайте за клавиатуру приятеля и смотрите, не покажет ли он время лучшее, чем ваше. Можете посмотреть, кто из вас покажет лучшее время из 10 заездов. И тому подобное.
Не удивляйтесь, что скорость на спидометре не равна пути, деленному на время. Ведь это мгновенная (то есть настоящая скорость в данное мгновение), а не средняя скорость автомобиля (см. Физика, 9 класс).
Все эти правила я старался сделать как можно проще, чтобы не усложнять проект. Разобравшись в проекте, вы всегда сможете дописать процедуры, делающие процесс гонки более для вас привлекательным.
Для проекта я выбрал вариант игры с одним автомобилем. Я вам намекну, как модифицировать проект, чтобы получилась игра с двумя автомобилями. Однако помните, что для грамотного создания игры с несколькими автомобилями вам нужно будет подняться на новый уровень программирования — научиться создавать собственные классы объектов.
Делим проект на части
Начнем создавать проект. Прежде всего, как положено, разделим его по возможности на части. Мы уже делили проект на части, когда создавали будильник. Сейчас вам очень полезно перечитать тот материал. И проглядеть ту программу.
Сразу же бросается в глаза, что наша задача распадается на две последовательные почти независимые части:
Сначала рисование поля и всех его элементов, выкатывание машины на старт, обнуление скорости, времени и пути — в общем, все то, что должно быть сделано после нажатия на кнопку Начинаем сначала, но до начала движения. Этим будет заниматься одна группа процедур.
Затем управление машиной и событиями во время гонки. Этим будет заниматься другая группа процедур. Мы полностью задействуем идею использования таймера, так, как я ее изложил в 0. На каждом импульсе таймера автомобиль должен будет проделывать весь цикл своего функционирования.
Первая часть
Поскольку в первой части нет движения, то, в общем, все равно, что именно рисовать сначала, что потом, но и здесь следование житейской логике дает некоторую экономию кода и смысла:
• Сначала нарисуем большой квадрат поля (ограждение), затем
• Рисуем старт
• Рисуем финиш
• Рисуем газоны
• Ставим машину на старт и обнуляем показания приборов
В общем, идеология первой части ясна. Пора разбираться в полном тексте программы, приведенном ниже. Здесь вам бы очень помогло, если бы программа уже находилась в вашем компьютере. Вам было бы легко и приятно в такт моим словам нажимать клавишу F8.
Начнем сверху. Разберитесь в объявленных переменных, не вникая пока в те, что относятся к движению.
Разобрались? Теперь идем дальше. Первая процедура, которая выполняется в проекте, это, конечно, Form Load. В каждом проекте в ней удобно программировать все действия и вычисления, которые нужно выполнить один раз за все время работы проекта, в самом начале. В нашем случае это в основном задание и вычисление значений переменных величин — размеров элементов поля игры. Кое-что здесь нуждается в пояснении:
Windowstate — это не переменная, а свойство формы. Вы помните, что свойства формы, в отличие от свойств других объектов, можно писать, не указывая хозяина (Form1.WindowState).
ScaleLeft и ScaleTop. Это тоже свойства формы. Мы их устанавливаем, если нам не нравится, что начало системы координат находится в левом верхнем углу формы. ScaleLeft занимается смещением начала координат по горизонтали, ScaleTop — по вертикали. Примеры:
Оператор ∙ Смысл
ScaleLeft = 1000 ∙ Начало системы координат смещается налево на 1000 твипов