Как сделать игру на blitz3d
games maker Все о создании игр и не только
15 февраля 2010 в 19:55
Итак, мы уже достаточно вооружены, чтобы сделать простенькую игру, так что хватит абстрактных примеров, а начнём уже делать игры, а то, что мы ещё не изучили, узнаем в самом процессе, по мере надобности…
Что это будет за игра? Сделаем такой вариант игры, которую делали в основах по BlitzBasic`у, только трёхмерный. Там у нас будет шарик, который будет ездить по плоскости, собирать, допустим, жёлтые кубики, и умирать от столкновения с красными… короче, сюжет стандартный…
Начнём с того, что создадим шарик игрока и его управление… (ну и камеру со светом):
Итак, всё просто – есть шарик, который ездит где-то внизу и поворачивается… вот только одно меня здесь смущает – не понятно, куда этот шарик повёрнут – он везде круглый, не видно, где перед, где … гм… это… зад. У меня вот такое решение этого вопроса – что если сделать у него такой мини хвост – как у капли или метеора? Т.е. здесь просто бы подошёл конус. Можно, конечно, сделать ещё один объект – как раз конус и просто сделать привязку к шару, но привязки полезны, когда нам нужно обязательно 2 различных объекта, а не один, или, например, если привязка через некоторое время должна пропасть… здесь же нам желателен объект, представляющий из себя цельный меш. Можно сделать модельку в 3ДМаксе, конечно, а потом её сюда загрузить, вот только зачем забивать лишнее дисковое пространство на модельки… которые мы сами можем сделать в самом Блитце! Как? Очень просто – присоединив к мешу шара меш конуса!
Вот как мы поступим (после создания шара):
Здесь мы создаём конус по имени Plac, вертим его там и по всякому подгоняем. Так как после создания шар будет стоять в точке 0,0,0 – конус будет ровно подогнан к нему – можете запустить и посмотреть… Вот только если вы будете этот шар двигать, конус останется на месте (естественно ). Итак, как я уже говорил, можно этот конус привязать (особой разницы не будет), но всё таки основываясь на программерскую этику, сделаем из них один объект (у нас есть возможность, да и зачем нам 2 объекта вместо одного).
Эта команда добавляет один меш к другому… то есть в данном случае мы добавляем меш конуса к мешу шара. НО! При этом сам объект конуса не исчезает (то есть мы этот конус как бы добавляем копированием). Короче, теперь у нас 2 меша – шар присоединённый к конусу, и сам конус, который нам сейчас не нужен. Поэтому (опять новая команда) мы его уберём:
Эта команда убирает заданный объект (в данном случае конус) и (самое главное) очищает от него память. Когда будете делать большие игры, где будет много уровней, при выходе из одного из них, не забывайте очищать ненужные объекты, иначе они будут копиться и занимать память, которая (L) не резиновая, в результате всё будет тормозить после определённого времени «играния»…
Дальше… не будет же этот шарик просто так ездить по полю! Надо создать ему определенные препятствия. Создадим-ка мы кубики, и разбросаем их по нашему будущему полю:
Здесь мы, как вы видите, создаём массив на 30 элементов, и затем расставляем в них кубики. А сами кубики раскидываем в случайном порядке по полю.
Так… кубики есть… столкновения нету… вывод: надо вставить сюда наш коллизион детекшн, который мы так старательно изучали в прошлой главе!
Сначала мы должны определить 2 константы для наших объектов – для шарика и для кубиков:
Вставьте эту строчку после инициализации графики – т.е. в начало… так типы есть, осталось только указать что шар и кубики к ним принадлежат:
Эту строчку поставьте после создания самого объекта шарика- т.е. после присоединения к нему конуса…
А эту вставьте в конец цикла создания кубиков (После команды PositionEntity Walls(i)…)
Так, типы задали, конечно, но сталкиваться они всё равно не будут – пока мы прямо не укажем, что они, мол, сталкиваться должны.
Здесь мы задали, что TypePlayer – который у нас является шаром должен сталкиваться с TypeWalls – т.е. с кубиками, соприкасаясь методом сфера к полигону, полностью скользя по нему. Можно последнюю цифру заменить на 1 – тогда шарик будет как бы «прилипать» к кубикам. Эту строчку поставьте после создания всех кубиков…
Хочу сразу заметить: (из своего опыта) команды Collisions нужно ставить одной из последних – т.е. сначала нужно инициализировать все предметы, затем их все расставить по местам, и только ПОТОМ обозначать коллизии между ними… можно, конечно сразу задать константы, и все столкновения между этими константами, но потом, когда вы будете создавать объекты, помните, что создаются-то они все в одной точке – 0,0,0 и получается, что находятся друг в друге, и затем, когда мы будем их расставлять, могут появиться баги – т.е. мы скажем объекту, типа, «Поставься в точку 0,10,100», а он окажется в точке 0,8,70 (или типа того), и можно долго ругаться, вспоминая его материнские отношения … либо в таком случае нужно делать так: создавать объекты, и тут же их переставлять в новые места… но, по-моему то как я предложил – лучше. (Scaven никогда не обманывает!)
Но уже что-то вырисовывается!
По традиции – полный код всего этого безобразия:
Создать игру, Конструкторы игр, Игровые движки, Разработка игр, Игровые ресурсы
10 Лучших пользователей
/—>
Партнеры сайта |
. |
Примеры ЛОЖНЫХ условий: Синтаксис условия IF-THEN: Примеры: Можно записать и так: ELSE можно и не включать: Программа, проверяющая пароль (10 мин) Программа, проверяющая, больше ли пятидесяти введенное число (10 мин) Бесконечные циклы (5 мин) Циклы этого типа понадобятся в дальнейшем для осуществления бесконечного повторения опроса клавиатуры и визуализации трехмерной сцены в соответствии с изменениями параметров трехмерных объектов. Управление камерой с клавиатуры (25 мин) на следующие: Устанавливаем углы поворота камеры: Визуализируем трехмерный мир: Примеры использования функций: Игра «Угадай число» (25 мин) Компьютер загадывает число: Бесконечный цикл, чтобы игрок мог пытаться угадывать число несколько раз: Играющий угадал число, поздравляем его с победой и выходим: Число больше задуманного: Число меньше задуманного: Задание: изменить программу так, чтобы у играющего было только 8 попыток, количество попыток выводилось на экран и при их исчерпании выводилось сообщение о проигрыше (10 мин) Если попыток больше восьми, то выходим с сообщением о проигрыше: Выводим количество попыток на экран: Группирование объектов (10 мин) Этот объект не отображается на экране, но имеет все параметры трехмерного объекта (координаты, углы поворота, масштаб). Затем, «привяжем» все части объекта к пустому, указав при их создании параметр «род» = piv. А эта команда позволяет создать массу объектов, идентичных созданному. Причем, при изменении исходного объекта, меняются и все его копии. Добавим в каждый оператор создания объекта созданный «родительский» объект, заменим, например на Затем, создадим цикл (перед командой RENDERWORLD): Итак, программа: fir = CREATEPIVOT() Также, текстуру можно масштабировать командой: Программа «Лес на траве» (10 мин) Загружаем текстуру: Увеличиваем текстуру в 50 раз: Но на зеркало нельзя наложить текстуру, поэтому для создания зеркальной поверхности мы должны применить такой прием: установить прозрачность затекстурированной плоскости и создать на ее месте зеркало. Создаем зеркало: ENTITYTEXTURE cyl, wood Затем можно работать с ней, как с обычным трехмерным объектом. Часто модели уже оттекстурированы и имеют ссылки на файлы текстур, применять к таким моделям команду ENTITYTEXTURE не стоит. В принципе, можно навести любой объект на любой другой. Изменим размеры модели: Создадим бесконечный цикл, команды для изменения положения робота и условия, изменяющие координаты при нажатии соответствующих клавиш: Наводим камеру на робота: Если нажата клавиша «вверх», перемещаем робота на вектор с длиной 0.5 под углом ang: Выходим, если нажата клавиша ESC: RENDERWORLD Каждый такой файл содержит одну последовательность фаз движения (скажем, бег или прыжок). Можно наложить на этот же объект еще одну последовательность фаз с помощью команды: Чтобы анимировать модель, нужно задать параметры анимации с помощью команды: rx# = 10 Прибавляем к переменной ry# приращение: Как сделать игру на blitz3dПара слов о функциях AppTitle «MY FIRST GAME» AppTitle «MY FIRST GAME» UpdateWorld А после установки графического режима допишите строчку: UpdateWorld Надеюсь, вам все понятно. Если же вам ничего не понятно, то пробегитесь по этому тексту еще раз, и вам станет понятно. Если вы снова пробежались по тексту, но вам все еще не понятно, то мне вас жаль. Волшебные функции AppTitle «MY FIRST GAME» UpdateWorld Эта строка, как вы догадались, подключает к главному файлу побочный файл. Такие файлы удобны для хранения собственных функций, чтобы не загромождать основной файл. Функция PositionEntity перемещает объект относительно мировой системы координат. Теперь это будет выглядеть так: Collision Detection Теперь надо присвоить эти коллизионные типы нашим объектам. Сразу после строчки создания сферы пишем: Теперь наша сфера не сможет пройти сквозь плоскость, в чем мы сейчас и убедимся – пора писать функцию Update(), отвечающую за обновление игрового мира. Для начала надо сделать глобальными обьекты камеры и игрока. Для этого в начале главного файла (где объявляли типы коллизий) пишем: y_speed#=y_speed#-0.01 – эта строчка отвечает за гравитацию. Переменная скорости объекта по оси У будет немного уменьшаться при каждом выполнении функции. Тут должно быть все понятно. Функция RotateEntity – тоже самое, что и PositionEntity, только с вращением вместо передвижения. Посмотрите вниз. Не знаю, как у вас, но у меня видно сферу-игрока. Нам нужно убрать ее, при этом не убрав коллизии. Есть функция HideEntity, но она не подойдет (попробуйте, сами поймете почему). Остается сделать ее прозрачной. Для этого сразу после создания сферы вставьте строку: Теперь сферу не видно. Эта функция задает прозрачность объекта (от 0 до 1). Попробуйте сделать прозрачность 0.5 и посмотрите, что будет. Смысл: если nojump – истина, то игрок может совершить прыжок, если ложь – то не может. Нетрудно догадаться, что ложью эта переменная будет тогда, когда игрок не касается пола – чтобы он не смог улететь при прыжке. If KeyHit(57) – если щелкнута (одиночное нажатие) клавиша пробел Вот и все, основа игрового движка закончена. Теперь я обещал показать, как экспортировать архитектуру из 3D MAX’a. Для начала посмотрим, какие текстуры вы будете использовать в вашем домике. Я выбрал две стандартные текстуры из 3D MAX’a. Эти текстуры надо поместить в папку Media. Туда же мы будем экспортировать домик. Учить основам 3D MAX’a я вас не буду, поэтому смотрите сразу, что у меня получилось: Потом экспортируем модель дома в формате *.3ds (файл-экспорт). Самое важное – не снимайте галочку с пункта Preserve Max Texture Coordinates. Теперь в функции Create_world() пишем строчки: house=LoadMesh(«media\house.3ds») Строчки Positionentity и ScaleEntity здесь подходит только для моего случая – так как у вас могли получится дома других размеров. Позиционируйте и масштабируйте дом так, чтобы он находился на земле и был приличных размеров. Отныне в дом можно войти, побегать в нем и выйти наружу. Вот почему я говорил, что текстуры и модели должны храниться в одном месте – текстуры автоматически «натянутся» на объект. Вот вы и получили первые сведения о Blitz3D и научились создавать в нем простую бродилку. Если буду жив, то напишу следующую часть этой статьи, где мы продолжим создавать эту игру – сделаем небольшую улицу, врагов и примитивный сценарий. Автор: SecondKosta
|