Основы программирования.
В предыдущих выпусках рассылки мы получили базовые знания по
программированию на DarkBASIC-е. На уроках, которые начались сегодня,
мы в конце научимся делать трёхмерные игры а-ля "Крутой Сэм" :-)) Короче,
тема этого цикла уроков "Создание 3D-игры". А после того, как закончим
делать игру по "Руководству по созданию 3D-игр" - добавим в нее почти настоящую
Атмосферу Земли, что придаст нашей игре неописуемую реалистичность!
Далее первые три урока.
Для более детальной и полной информации - рекомендую обратиться к
первоисточникам. А это компания "Медиахаус" и "Руководство пользователя",
которое вы получаете в коробке с лицензионным DarkBASIC-ом.
РУКОВОДСТВО ПО СОЗДАНИЮ 3D-ИГР
I. ОСНОВЫ
1.Набор команд "sync"
Цель урока: познакомиться с командами обновления экрана DarkBASIC и уяснить их важность.
Давайте начнем урок с программы, которая рисует на экране 3D-сферу.
Sync On
Make Object Sphere 1,100
Do
Sync
Loop
А теперь объясним, как команды рисуют и выводят на экран сферу.
Sync on
Команда "Sync on" дает указание DarkBASIC обновить изображение на экране, когда будет вызвана команда "Sync". Вам не обойтись без этих команд ни в одной программе на DarkBASIC.
Make Object Sphere 1,100
Как и большинство команд DarkBASIC, "Make Object Sphere" очень легко понять - конечно, если вы знаете английский язык. Она дает указание DarkBASIC создать объект в форме сферы. А каково назначение двух цифр в конце команды? Первая цифра "1" обозначает номер объекта, который нужно ввести в программу. Числа в DarkBASIC выполняют ту же функцию, что и имена. Они сообщают программе, какой именно объект нужно переместить по экрану, изменить или, как в нашем случае, создать. Второе число, "100", - это радиус вашей сферы.
Do
Loop
Команды "Do" и "Loop" используются для создания в программе цикла. Любые команды, помещенные вами между "Do" и "Loop", будут выполняться непрерывно, пока, находясь в редакторе, вы не нажмете клавишу "ESC" или "F12". Почти во всех программах, которые вы напишите, будет подобный цикл. Обычно его называют "основным" или "игровым" циклом. В нашем случае мы вставили между "Do" и "Loop" команду "Sync".
Sync
"Sync" означает "синхронизировать" . Когда программа меняет положение объекта, значения нового положения записываются в память, но не влияют на изображение 3D-сцены. Если синхронизацию отключить, экран будет обновляться всякий раз, когда меняются какие-либо значения, а иногда он не будет обновляться вовсе. В результате ваша программа станет выполняться медленно, но может случиться так, что экран останется пустым. Команду "Sync" можно сравнить с занавесом в театре. Когда подходит время поменять что-либо на 3D-сцене, "занавес" опускается, "декорации" меняются, и команда "Sync" снова поднимает "занавес". Она, как правило, вызывается только один раз в конце основного цикла программы, но бывают исключения.
Надеемся, что вы уяснили предназначение команды "Sync". Добавим теперь к ней команду "Sync Rate".
Давайте завершим наше обсуждение команды синхронизации и познакомимся с новой командой "Sync Rate".
Sync On
Sync Rate 30
Make Object Sphere 1,100
Do
Sync
Loop
Команда "Sync Rate" позволяет установить постоянную частоту обновления экрана. Частота обновления - это то, сколько раз в секунду поднимается и опускается "занавес" перед вашей сценой. Постоянная частота обновления нужна для согласованности работы программы на разных компьютерах. Если на вашем компьютере экран обновляется со скоростью 40 кадров в секунду, то на более производительном компьютере вашего друга он может обновляться со скоростью 120 кадров в секунду, а это слишком быстро. Установив постоянную частоту обновления (в нашем примере - "30"), вы добьетесь того, что экран будет обновляться с одной и той же скоростью на всех компьютерах. Человеческий глаз устроен так, что способен воспринимать скорость обновления экрана до определенных пределов, поэтому если вы установите слишком большую частоту, то будете зря расходовать ресурсы компьютера. А если частота обновления окажется слишком низкой, то движения на экране будут прерывистыми и медленными. Есть одно исключение: частоту обновления можно установить равной "0". Тогда DarkBasic будет обновлять экран с максимально доступной скоростью.
Итак, мы познакомили вас с набором команд синхронизации. Теперь вы сами сможете установить частоту обновления экрана, понимая, как и когда это нужно делать. Вы также узнали простейшие команды DarkBASIC, которые работают с объектами. Попробуйте изменить или добавить в программу следующие команды. Также попробуйте поменять значения ширины, высоты и глубины и посмотрите, как они влияют на изображения создаваемых вами объектов. В команде "Make Object Triangle" задайте различные значения "x", "y" и "z" и посмотрите, какие удивительные треугольники у вас получатся. Убедитесь, что каждому объекту присвоен уникальный номер. Для этого вместо слов "Номер объекта" поставьте физическое число, соответствующее конкретному объекту. (Это относится ко всем случаям, где рядом с именем команды присутствуют слова "Номер объекта".)
MAKE OBJECT CUBE Номер объекта, Значение размера
MAKE OBJECT BOX Номер объекта, Ширина, Высота, Глубина
MAKE OBJECT CYLINDER Номер объекта, Значение размера
MAKE OBJECT CONE Номер объекта, Значение размера
MAKE OBJECT PLAIN Номер объекта, Значение ширины, Значение высоты
MAKE OBJECT TRIANGLE Номер объекта, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3
2. Ввод данных с клавиатуры и преобразование объектов.
Цель урока: показать, как можно изменять положение объекта на экране с помощью клавиш.
Начнем урок с знакомства с командной "Rem" - прекрасным инструментом для создания собственных записей ("комментариев") в программе. Эта команда дает указание DarkBASIC пропускать все, что находится в строке после слова "Rem". Со временем ваши программы будут становиться все сложнее и сложнее, и вы будете тратить все больше времени на их написание, и вскоре начнете забывать, для чего предназначена та или иная переменная, и что именно делает тот или иной блок исходного кода. Именно для таких случаев служит команда "Rem" и вставленные комментарии, которые будут обо всем этом напоминать. Этот инструмент удобен также, если в процессе работы над проектом вы передаете исходный код своей программы коллегам и друзьями или когда одновременно работаете над несколькими разными проектами.
Rem Устанавливаем частоту обновления экрана
Sync On
Sync Rate 30
Rem Создаем сферу
Make object cube 1,100
Rem Основной цикл
Do
Rem Сохраним вертикальный угол (по оси Y) объекта в переменной aY#
aY# = Object angle Y(1)
Rem Управление вводом данных
If Upkey()=1 then Move object 1,2
If Leftkey()=1 then aY# = Wrapvalue(aY#+5)
If Rightkey()=1 then aY# = Wrapvalue(aY#-5)
Rem Вращаем сферу
Yrotate object 1,aY#
Rem Обновляем экран
Sync
Loop
Вы, вероятно, узнали часть кода из предыдущего урока. Не удивляйтесь, если в последующих уроках вам будут встречаться знакомые блоки кода. Если какая-либо команда покажется вам незнакомой и останется в уроке без объяснений, вернитесь к предыдущим урокам, чтобы освежить память, или обратитесь к справочной системе DarkBASIC.
А сейчас поговорим о переменных. Переменная - это величина, способная принимать разные значения и используемая для их хранения. В DarkBASIC применяется несколько типов переменных, различаемых по расширению. Взгляните на эту строку из нашего примера.
aY# = Object angle Y(1)
В переменной "aY#" мы сохранили значение угла "Y" объекта "1". Обратите внимание на символ "#" в конце выражения "aY#". Он сообщает DarkBASIC, что нам нужно сохранить в переменной значение с плавающей точкой, то есть, число с десятичным знаком, например, 3.5, -5.5 и 0.00001. Такая переменная (она называется вещественной) позволяет хранить дробные числа, ее можно использовать для хранения координат или значения угла. Другие типы переменных в DarkBASIC - это символьные переменные, переменные для хранения массивов данных и переменные целого типа. Для обозначения символьных переменных используется символ "$", например, "A$ = "Здравствуй, мир" ". Данные, которые вы хотите сохранить в символьных переменных, должны заключаться в кавычки. В переменных для хранения массивов данных хранятся наборы данных одного и того же типа. Мы рассмотрим массивы в последующих уроках. Переменные целого типа хранят целые числа, как положительные, так и отрицательные, например, -5, 5, 2112, -10000. Для обозначения таких переменных расширение не используется. Как назвать переменные, решайте сами, но помните, что лучше давать им имя, близкое по смыслу к тому, что эти переменные хранят. Это окажется полезным при отладке программы и обсуждении вашего исходного кода с друзьями. Мы назвали переменную "aY#", чтобы ее имя напоминало нам о том, что в ней хранится значение угла "Y" объекта "1". Обратите внимание, что мы не используем полное название "AngleY#" (Угол Y#). По мере роста исходного кода вам придется много раз набирать на клавиатуре имена переменных. Сокращая имена, вы делаете свой код более легким для чтения и облегчаете себе работу.
Object angle Y(1)
Команда "Object Angle Y" возвращает значение угла объекта, если он поворачивается по оси Y. Ось Y, по которой вращается объект, - это вертикальная линия, проходящая снизу вверх. Можно сравнить ее с земной осью, вокруг которой вращается наша планета. Ось X - это горизонтальная линия, проходящая слева направо. По горизонтальной оси вращаются колеса автомобиля. Ось Z - это направление от вас вдаль, вращение по этой оси можно сравнить с вращением автомобильного руля. В команде "Object Angle Y" в скобках указывается номер объекта, данные о вращении которого (по оси Y) вы хотите узнать. Помните, что команду нужно писать точно так, как она указана в справке. В этой команде пробела между "Y" и первой скобкой нет. Если команду написать неправильно, DarkBASIC не узнает ее и примет за ошибку.
If Upkey()=1 then Move object 1,2
Выражение "If then" - очень мощная команда DarkBASIC, выполняющая функцию сравнения. Переменная, значение которой нужно проверить, помещается после "If". Если переменная имеет значение "Истина", то выполняются команды, стоящие после "Then". Если оно имеет значение "Ложь", то команды после "Then" не выполняются. В этом примере после "If" стоит команда "Upkey()". Она проверяет, нажата ли клавиша-стрелка вверх на клавиатуре и возвращает "1", если клавиша была нажата, и "0", если не была. Если клавиша нажата, выполняется команда "Move Object", перемещающая объект в том направлении, куда он "повернут лицом". Вслед за именем команды стоят числа, называемые параметрами. Первое число после команды "Move Object" - это номер перемещаемого объекта. Второе число обозначает количество единиц пространства сцены, на которые необходимо переместить объект каждый раз, когда выполняется эта команда.
If Leftkey()=1 then aY# = Wrapvalue(aY#+5)
If Rightkey()=1 then aY# = Wrapvalue(aY#-5)
Эти два выражения "If Then" проверяют, нажаты правая или левая клавиша-стрелка. Результаты нажатия этих двух клавиш разные. Используя эти выражения, мы также сохраняем значение в переменной "aY#". Команда "Wrapvalue" позволяет нам сэкономить целый блок программного кода. Дело в том, что команды вращения в DarkBASIC принимают значения только от 0 до 360. Этот диапазон чисел используется для вычисления угла поворота, а команда "Wrapvalue" отслеживает, чтобы значение не выходило за границы этого диапазона. Значение 365 будет преобразовано в 5. Внутри скобок команды "Wrapvalue" мы поместили нашу переменную угла по оси Y и оператор сложения или вычитания. Если нажата левая клавиша, к значению "aY#" прибавляется 5, а затем новое значение сохраняется в "aY#". То же самое происходит, если нажата правая клавиша, только в этом случае значение переменной "aY#" уменьшается на 5.
Yrotate object 1,aY#
Команда "Yrotate object" поворачивает объект по оси Y на указанное число градусов. Первое число после команды обозначает номер объекта, второе - угол, на который нужно повернуть этот объект. Обратите внимание, что во втором параметре вместо числа использована переменная. В параметрах большинства команд DarkBASIC числа можно заменять переменными.
Затем мы используем команду "Sync", чтобы открыть занавес вашей сцены и вывести на экран новое положение объектов.
Попробуйте изменить значение, прибавляемое или вычитаемое из переменной в команде "Wrapvalue", чтобы ускорить или замедлить вращение.
Попробуйте также поменять значение второго параметра в команде "Move Object", чтобы увеличить количество пространственных единиц, на которые перемещается объект. Можно использовать значения с плавающей точкой, например, 0.5 или 1.5. Если число меньше единицы, то перед десятичным знаком лучше всегда ставить "0".
Попробуйте поменять команду "YRotate Object" на команду "ZRotate Object" или "XRotate Object", чтобы посмотреть, как будут поворачиваться объекты.
3. Перемещение камеры
Цель урока: показать, как нужно изменять положение и угол поворота камеры с помощью ввода с клавиатуры.
Rem Устанавливаем синхронизацию
Sync On
Sync Rate 30
Rem Создаем 5 кубиков и расставляем их в случайном порядке
For x = 1 to 5
Make object cube x,100
Position object x,Rnd(2000),0,Rnd(2000)
Next x
Rem Основной цикл
Do
Rem Сохраняем угол поворота камеры
caY#= Camera angle Y()
Rem Управление камерой с клавиатуры
If Upkey()=1 then Move camera 10
If Leftkey()=1 then Yrotate Camera Wrapvalue(caY#-5)
If Rightkey()=1 then Yrotate Camera Wrapvalue(caY#+5)
Rem Обновляем экран
Sync
Loop
Для начала познакомимся с циклом "For Next".
For x = 1 to 5
Make object cube x,100
Position object x,Rnd(2000),0,Rnd(2000)
Next x
Цикл "For Next" применяется для выполнения одной или нескольких команд заданное число раз. Чтобы указать, сколько раз этот цикл должен выполняться, мы используем переменную "x". В выражении "For Next" для этого всегда нужно ставить слово "To". В нашем случае мы выполняем цикл 5 раз - от 1 до 5. Необходимые команды помещаются в тело цикла. Оператор "Next" с переменной "x", которая подсчитывает число проходов по циклу, обозначает его завершение и увеличивает значение "x" на единицу. Внутри цикла мы создаем объекты в форме куба, присваивая им номер с помощью той же переменной "x". Затем команда "Position Object" помещает на сцене объект в соответствии со значениями 3D-координат. Первое число в команде "Position Object" - это номер помещаемого в сцену объекта. Мы заменили его переменной "x". Три значения после номера объекта обозначают координаты X, Y и Z. Вместо чисел мы поставили команду "Rnd", которая создает случайное число от 0 до значения, находящегося в скобках. Каждый раз при вызове команды "Position Object" новый объект помещается в случайных координатах X и Z с координатой Y, равной 0.
If Upkey()=1 then Move camera 10
Следующая наша команда - "Move Camera". Она похожа на команду "Move Object" за исключением того, что не нужно указывать номер объекта. Число после команды обозначает количество единиц, на которое требуется переместить камеру при каждом проходе основного цикла, если нажата клавиша-стрелка вверх.
If Leftkey()=1 then Yrotate Camera Wrapvalue(caY#-5)
If Rightkey()=1 then Yrotate Camera Wrapvalue(caY#+5)
Команда "YRotate Camera" выполняет ту же функцию, что и "YRotate Object", только она поворачивает по оси Y не объект, а камеру.
Таким образом, вы получили представление, как нужно перемещать камеру и изменять ее положение. Чтобы лучше понять все команды, попробуйте изменить текст исходной программы.
Измените значения в команде "Rnd", чтобы посмотреть, как меняется положение объектов относительно друг друга.
Измените значения в командах "Move Camera" и "Yrotate Camera", чтобы посмотреть, как можно замедлить или ускорить перемещение и поворот камеры.