Навигация по сайту
- Игры / Образы
- Игры на русском языке
- Коды / Советы / Секреты
- Наши переводы
- Наши проекты
- Игры на русском языке (OnLine)
- Эмуляторы
- Обзоры игр
- Информация
- Статьи
- Интервью
- Мануалы / Инструкции
Случайная игра
Вступай!!!
Облако тегов
Показать все теги
Создай 3D-игру на Blitz3D
Как создать простую трехмерную бродилку в Blitz3D?
Как создать простую трехмерную бродилку в Blitz3D?
Blitz 3D
Это мощный и необычайно легкий в использовании язык программирования для создания видеоигр. Вы сможете создавать 3D, 2D-пазлы, приключения (adventures), RPGS. Blitz основан на таком популярном языке программирования, как BASIC. Компилирует удивительно быстрый код. Инструмент идеален как для профи, так и для начинающих.
Это мощный и необычайно легкий в использовании язык программирования для создания видеоигр. Вы сможете создавать 3D, 2D-пазлы, приключения (adventures), RPGS. Blitz основан на таком популярном языке программирования, как BASIC. Компилирует удивительно быстрый код. Инструмент идеален как для профи, так и для начинающих.
В мире существует множество конструкторов игр без программирования. В этих конструкторах, используя простейшие скрипты (а иногда и без них), любой человек может создать свою собственную игру. Но многие из этих конструкторов очень ограничены в жанровом направлении или возможностях. Эта статья познакомит вас с очень популярным языком программирования – Blitz 3D. Если вы уже выбрали себе конструктор и успешно создаете на нем игры, то можете дальше не читать.
Если же вас не удовлетворяют возможности ни одного конструктора, которые вам пришлось повидать, то эта статья для вас. Она рассчитана на человека, который впервые видит Blitz3D (но который учил в школе Pascal, и знает, что такое переменная и цикл). По ходу чтения этого текста вы создадите свою первую трехмерную игру - небольшую бродилку. В ней не будет ни сюжета, ни врагов, зато вы получите знания, необходимые для создания более сложных игр.
Несколько слов о Blitz3D.
Blitz 3D - это язык программирования, созданный специально для написания 3D игр (можно, конечно, и 2D, но нас это не интересует). Он очень прост в изучении для новичка. Его графические возможности не очень впечатляют (DX 7), но для начинающего - в самый раз.
Где его можно добыть?
Blitz 3D очень распространен в сети - наберите в Google или Rambler'e Blitz 3D, и поищите, где его можно скачать. Проблем с этим возникнуть не должно. Еще нам понадобится любая версия 3D Max'a (автор статьи использует 5-ую версию). Если у вас нет 3D Max'a - то идите и раздобудьте его у друзей, одноклассников (однокурсников), на худой конец у учителя по информатике или в каком-нибудь другом месте.
Начало работы.
Если весь необходимый софт есть, то можно начать работу.
Для начала создайте папку для своей будущей игры. В ней создайте еще одну папку - Media (если хотите - назовите по-другому, но в этом туториале я буду использовать это имя). В ней вы будете хранить модели и текстуры. Модели и текстуры лучше хранить в одном месте (потом объясню почему). Называйте все свои подпапки и файлы английскими именами, так как Blitz в упор не хочет видеть кириллицу.
Затем, в вашей главной директории, создайте главный файл игры - game.bb (назовите этот файл так же как я, потому, что я буду ссылаться на него, и чтобы вам, новичкам, не запутаться)
В этом файле будет прописан основной код игры.
Ну что, еще не испугались того объема информации, который вам предстоит сейчас усвоить? Главное - понимать сразу каждую строчку, а не тупо списывать текст программы, чтобы посмотреть результат. Возможно, вам будет что-то непонятно - в этом случае набирайте код снова и снова, пока до вас не дойдет. Все, что зависит от меня - я сделаю, буду писать максимально понятно. Ну что, поехали!
Первые строчки - введение в мир Blitz3D
Загрузите файл game.bb в Blitz3D.
(существует множество оболочек, облегчающих работу в Blitz, но я в этом туториале буду ссылаться на интерфейс стандартной оболочки, потому что она стоит у большинства новичков).
Перед вами откроется пустое окно для ввода программы. Мне следует рассказать об интерфейсе Blitz3D. Справа - окошко поменьше, в нем отображаются ваши функции, типы и метки (обо всем этом - попозже). Нажимая на кнопки funcs, types или labels, вы выбираете, что же именно из этого будет отображаться.
Вверху - ряд кнопок. Первые четыре из них - стандартные для любого редактора - New, Open, Save и Close. Как вы уже догадались, это Новый файл, Открыть файл, Сохранить файл и Закрыть файл соответственно. Потом идут кнопки буфера обмена - Копировать, Вырезать и Вставить (возможно, некоторых из вас бесит, то, что я как маленьким тупым детям объясняю названия кнопочек - просто не у всех есть навык работы с Blitz3D, а этот туториал - для полных, извините, новичков. Поэтому, если вы уже знакомы со средой Blitz3D, то можете переходить к следующей части туториала). Кнопка с лупой - это поиск в тексте программы словосочетания, а ракета - тест программы, компиляция и запуск вашей писанины.
Пара слов о функциях
Функциями в языке программирования называют слова, которые выполняют какое-либо действие. Зачастую, чтобы упростить структуру программы в Blitz3D, программисты пишут собственные функции. Вам тоже придется этим заниматься.
Рассуждать можно вечно, но пора уже писать программу.
Для начала нужно задать графический режим, то есть установить разрешение экрана, глубину цвета и полноэкранность вашей игры.
Для этого напишите:
Graphics3D 800,600,32,2
Эта функция и устанавливает графический режим, создает окно вашей игры.
800 и 600 - это разрешение экрана вашей игры (для начала сойдет такое), 32 - глубина цвета, а последняя цифра значит, что окно не полноэкранное. Если вы вместо 2 напишите 1, то окно станет полноэкранным.
Теперь нажмите на ракету, чтобы запустить вашу программу. Появится черное окно без заголовка размером 800 на 600 и сообщение, что ваша программа завершилась. Нам надо сделать две вещи - сделать заголовок окна и убрать это сообщение, чтобы программа спокойно завершалась.
Для этого используем команды AppTitle И End.
AppTitle "MY FIRST GAME"
Graphics3D 800,600,32,2
End
То, что пишется в кавычках после функции AppTitle - становится заголовком вашего окна. Обычно эта строчка пишется самой первой.
Надеюсь, смысл функции End объяснять не надо - она просто завершает вашу программу.
Теперь запустите вашу программу снова. Выскочит черное окно с заголовком "MY FIRST GAME" и сразу же завершится.
Теперь создадим главный цикл. Все действия, помещенные в этот цикл, будут повторяться бесконечно, пока не сработает определенное условие (например, пройдена игра или нажата клавиша Escape). После выполнения этого условия цикл завершается.
Цикл можно создать тремя разными способами, но мы используем самый понятный из них: через Repeat.
AppTitle "MY FIRST GAME"
Graphics3D 800,600,32,2
Repeat
Until Keydown(1)
End
Теперь объясняю все по порядку. Функция Repeat открывает цикл, действия, помещенные между Repeat и Until будут выполняться до тех пор, пока не выполнится условие, описанное после Until. В нашем случае - это нажатие клавиши Escape. Функция Keydown(a) проверяет, нажата ли клавиша, сканкод которой - а. Для клавиши Escape сканкод - 1. Полный список сканкодов можно найти во встроенной справке Blitz3D. Грубо говоря, программа будет выполняться, пока не нажата клавиша Escape. После ее нажатия, она благополучно завершится.
Теперь запустите программу. Ваше черное окно теперь никуда не исчезает.
Теперь дополним главный цикл:
Repeat
Cls
UpdateWorld
RenderWorld
Flip
Until Keydown(1)
А после установки графического режима допишите строчку:
SetBuffer BackBuffer()
Функция Cls очищает экран при каждой итерации (выполнении тела цикла).
Функции UpdateWorld и RenderWorld проверяют коллизии и рендерят мир в задний буфер соответственно. (Вам не нужно знать, что это такое, просто пишите эти строчки, если хотите что-нибудь увидеть на экране).
Функция SetBuffer BackBuffer() устанавливает задний буфер в качестве активного.
Функция Flip отражает изображение с заднего буфера на передний. (Опять же, вам не обязательно знать, как это работает, просто пишите это каждый раз в конце главного цикла).
Это была техническая часть вашей программы - обеспечение отображения игры на экране монитора. Полностью этот код выглядит так:
AppTitle "MY FIRST GAME"
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
Repeat
Cls
UpdateWorld
RenderWorld
Flip
Until KeyDown(1)
End
Надеюсь, вам все понятно. Если же вам ничего не понятно, то пробегитесь по этому тексту еще раз, и вам станет понятно. Если вы снова пробежались по тексту, но вам все еще не понятно, то мне вас жаль...
Волшебные функции
Теперь добавим в текст программы три функции: (если кто не понял, то, что написано черным, в Blitz3D писать не надо, это мои комментарии. Если вы додумаетесь написать мои комментарии в программе, то она не запустится).
AppTitle "MY FIRST GAME"
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
Create_player() - эта функция создаст объект игрока и все, то с ним связано
Create_world() - эта функция создаст мир вокруг игрока - землю, здания и др.
Repeat
Cls
Update() - эта функция будет обновлять игрока и мир (если это необходимо) каждую итерацию цикла
UpdateWorld
RenderWorld
Flip
Until KeyDown(1)
End
Вот, собственно, ваша первая игра готова... Запустите ее... Конечно, так просто ничего не бывает. Она выдаст вам ошибку... Естественно, таких волшебных функций, которые помогут вам создать игру в 13-15 строчек не существует... У нас есть лишь один выход - написать их самим!
Создайте еще один файл Blitz3D, назовите его functions.bb
Поместите этот файл в директорию нашей игры.
Именно в этом файле мы напишем три функции, которые так упрощают текст нашей игры: Create_player(), Create_world() и Update().
Чтобы можно было из главного файла обращаться к функциям, написанным во второстепенном файле, нужно его подключить - после строки SetBuffer BackBuffer() напишите следующую строку:
Include "functions.bb"
Эта строка, как вы догадались, подключает к главному файлу побочный файл. Такие файлы удобны для хранения собственных функций, чтобы не загромождать основной файл.
Теперь займемся написанием функций. Для начала нам нужно создать игрока. В качестве игрока мы выберем сферу - поскольку наша игра от первого лица, сферу видно не будет, а сфера лучше всего подходит для коллизий с объектами мира (для тех, кто не знает - коллизии - это столкновения. Они нужны, чтобы герой не проваливался сквозь пол и не проходил сквозь стены). Также необходимо создать камеру - глаза нашего персонажа. Она должна находиться чуть выше нашей сферы, чтобы обеспечить правдоподобный обзор. Чтобы видеть грани объектов, нужно создать источник света. Вот вроде и все для начала. Перед тем, как писать функцию, хочу сказать пару слов о родительской привязке. Это такой метод привязки объектов, когда "ребенок" полностью зависит от "родителя" - если объект-"родитель" вращается, масштабируется или передвигается, тоже самое происходит и с "ребенком". А если изменяется "ребенок", то на "родителя" это никак не влияет. Таким образом, сферу мы сделаем "родителем", а камеру - "ребенком". То есть, камера будет перемещаться так же, как и сфера. Чуть позже вы увидите, как это удобно.
Теперь пора писать функцию Create_player(). Я напишу сразу часть функции, а потом буду объяснять. Сейчас будет очень много нового, запоминайте, и старайтесь не путаться.
Добавим эти строки в файл functions.bb
Function Create_player() - начало функции
player=createsphere(8) - создаем сферу под названием player. Команда пишется так: CreateSphere(сегменты, родитель) – где сегменты – количество сегментов, а родитель – имя объекта-родителя.
camera=createcamera(player) - создаем камеру под названием camera и укажем ей родителя - player
positionentity camera,0,2,0 - поместим камеру выше на 2 виртуальных метра (это условная мера длины). Первое число - по оси X (влево-вправо), 2-е -по оси Y (Вверх-вниз), третье - по Z (вперед-назад). Это сложно, нужно тупо запомнить это раз и навсегда.
light=createlight(2) - создадим источник света под именем light
End Function
Функция PositionEntity перемещает объект относительно мировой системы координат.
Функции, начинающиеся на слово Create создают стандартные объекты - это просто надо запомнить. В скобках после них - дополнительные параметры - родитель (например, как у камеры) или параметр объекта. Для сферы - (в данном случае - 8) количество сегментов, чем из больше - тем более сфера похожа на сферу. Нашу сферу не видно, поэтому ее внешний вид нас не волнует - можно сделать сегментов поменьше. Родителя нужно указывать после всех параметров объекта. Эти параметры (если их несколько) разделяются запятой.
Для начала хватит. Позже мы расширим эту функцию. Но чтобы видеть, что мы творим, надо создать мир.
Для начала мир будет простой - бесконечная плоскость с простой текстурой. (потом, используя 3D Max мы создадим небольшое здание, где и будем бегать).
Настало время для текстуры. Достаньте какую-нибудь текстурку (или нарисуйте сами). Я взял текстуру травы в формате jpg из папки maps в 3D Max'е. Поместите ее в папку Media.
Function Create_world() - начало функции
plane=createplane() - создаем бесконечную плоскость под названием plane
positionentity plane,0,-2,0 - поместим плоскость немного ниже нулевой отметки
planetex=loadtexture("media\grass.jpg") - загрузим текстуру из папки media и присвоим ей имя planetex planetex
entitytexture plane,planetex - протекстурируем обьект плоскости только что загруженной текстурой
End Function
Еще создайте пустую функцию Update(): (Ее мы напишем чуть позже)
Function update()
End Function
И можно любоваться своими трудами.
Если текстура кажется вам мелкой и однообразной – можно увеличить ее командой ScaleTexture:
Добавьте в функцию Create_world после загрузки текстуры следующую строку:
ScaleTexture planetex,4,4
Эта функция растягивает текстуру в определенное кол-во раз (первое число – растяжение по оси Х, а второе – по оси У)
Теперь это будет выглядеть так:
Collision Detection
Теперь самое сложное, но самое необходимое… Коллизии!
Для начала необходимо создать два переменные коллизий: коллизионный тип игрока и коллизионный тип мира (в нашей упрощенной до невозможности игре только одно взаимодействие – разницы между стеной, полом и потолком не будет).
Для этого в главном файле перед функциями создания игрока и мира объявим две глобальные переменные (надеюсь, вы знаете, что такое переменные?)
Global playerT=1
Global wallT=2
Глобальные переменные значат то, что их можно использовать во всей программе. Есть еще и локальные переменные (Local), которые можно использовать лишь в пределах одного цикла или одной функции.
Теперь надо присвоить эти коллизионные типы нашим объектам. Сразу после строчки создания сферы пишем:
EntityType player,playerT
Аналогично для плоскости:
EntityType plane,wallT
Теперь остается только объявить коллизии.
В конце функции Create_player() пишем строчку:
Collisions playerT,wallT,2,3
Это означает, что объект с типом коллизии PlayerT будет взаимодействовать с объектом с типом коллизии WallT по принципу sphere-to-polygon (за это отвечает двойка) с дальнейшим скольжением первого обьекта относительно второго (за это отвечает тройка). Это сложно, надо просто понять и запомнить.
Теперь наша сфера не сможет пройти сквозь плоскость, в чем мы сейчас и убедимся – пора писать функцию Update(), отвечающую за обновление игрового мира. Для начала надо сделать глобальными обьекты камеры и игрока.
Для этого в начале главного файла (где объявляли типы коллизий) пишем:
Global player,camera
Также нам нужно объявить глобальными переменные, отвечающие за перемещение игрока:
Global x_speed#,y_speed#,z_speed#
Эти три переменные – значения скорости игрока по всем трем осям. Решетка после них означает, что они – переменные с плавающей точкой (Float), короче говоря, дробные.
Теперь настало время написать функцию Update()
Она и будет отвечать за перемещение нашего героя по плоскости.
Function update()
MoveEntity player,player,x_speed#,y_speed#,z_speed# - функция MoveEntity перемещает объект относительно системы координат самого объекта на указанное расстояние по всем трем осям.
y_speed#=y_speed#-0.01 – эта строчка отвечает за гравитацию. Переменная скорости объекта по оси У будет немного уменьшаться при каждом выполнении функции.
If y_speed#750 then MoveMouse 400,300
If MouseX()550 then MoveMouse 400,300
If MouseY()80 Then crot#=80
If crot#<-80 Then crot#=-80
Тут должно быть все понятно. Функция RotateEntity – тоже самое, что и PositionEntity, только с вращением вместо передвижения.
Посмотрите вниз. Не знаю, как у вас, но у меня видно сферу-игрока. Нам нужно убрать ее, при этом не убрав коллизии. Есть функция HideEntity, но она не подойдет (попробуйте, сами поймете почему). Остается сделать ее прозрачной. Для этого сразу после создания сферы вставьте строку:
EntityAlpha player,0
Теперь сферу не видно. Эта функция задает прозрачность объекта (от 0 до 1). Попробуйте сделать прозрачность 0.5 и посмотрите, что будет.
Для полного счастья осталось сделать только прыжок.
Для начала обьявите глобальной логическую переменную nojump:
Global nojump=FALSE
Смысл: если nojump – истина, то игрок может совершить прыжок, если ложь – то не может. Нетрудно догадаться, что ложью эта переменная будет тогда, когда игрок не касается пола – чтобы он не смог улететь при прыжке.
Затем добавьте в функцию Update() следующий кусок кода:
If EntityCollided(player,wallT) – если игрок столкнулся с полом…
nojump=True – прыжок возможен
Else – а если нет - …
nojump=False - то невозможен
EndIf – конец условного оператора
If KeyHit(57) – если щелкнута (одиночное нажатие) клавиша пробел
If nojump=True – и если прыжок возможен
y_speed#=0.2 – скорость игрока по Y равна 0.2
EndIf
EndIf
Теперь игрок при нажатии клавиши пробел - невысоко прыгает. Если что-то непонятно, не стесняйтесь жать на клавишу F1.
Вот и все, основа игрового движка закончена. Теперь я обещал показать, как экспортировать архитектуру из 3D MAX’a.
Для начала посмотрим, какие текстуры вы будете использовать в вашем домике. Я выбрал две стандартные текстуры из 3D MAX’a. Эти текстуры надо поместить в папку Media. Туда же мы будем экспортировать домик. Учить основам 3D MAX’a я вас не буду, поэтому смотрите сразу, что у меня получилось:
Теперь текстурируем это дело, в качестве Diffuse Color используем те текстуры, которые скинули в папку Media. Потом к каждому объекту применяем модификатор UVW Map и выбираем Mapping – Box. Вот что получилось:
Потом экспортируем модель дома в формате *.3ds (файл-экспорт). Самое важное – не снимайте галочку с пункта Preserve Max Texture Coordinates. Теперь в функции Create_world() пишем строчки:
house=LoadMesh("media\house.3ds")
PositionEntity house,10,-19,0
ScaleEntity house,1,1,1
EntityType house,wallT
Строчки Positionentity и ScaleEntity здесь подходит только для моего случая – так как у вас могли получится дома других размеров. Позиционируйте и масштабируйте дом так, чтобы он находился на земле и был приличных размеров.
Вот что получится:
Отныне в дом можно войти, побегать в нем и выйти наружу. Вот почему я говорил, что текстуры и модели должны храниться в одном месте – текстуры автоматически «натянутся» на объект.
Кстати, добавьте в функцию создания игрока строку:
EntityRaduis player,1.5
И посмотрите, что изменилось – теперь вы не будете видеть сквозь стены, если упретесь в них. Попробуйте в этом же файле с моделью дома сделать еще домов, небольшую улицу…
Вот вы и создали свою первую эээ… игру. Конечно, это еще не игра, но уже первый шаг к созданию своей первой игры.
Вот вы и получили первые сведения о Blitz3D и научились создавать в нем простую бродилку. Если буду жив, то напишу следующую часть этой статьи, где мы продолжим создавать эту игру – сделаем небольшую улицу, врагов и примитивный сценарий.
Автор: SecondKosta
Журнал: TOF