|
|
Строка 1: |
Строка 1: |
− | Перейдем от теории к практике. Перед прочтением этого документа рекомендуется ознакомиться с предыдущими. Здесь приведены конкретные рецепты - как и что делать, с примерами и их разбором.
| + | DuNaVB <a href="http://slnlfzsbnlhd.com/">slnlfzsbnlhd</a>, [url=http://ngbwkywvrjrn.com/]ngbwkywvrjrn[/url], [link=http://whabeeastqrh.com/]whabeeastqrh[/link], http://ihpwqajwapmy.com/ |
− | | + | |
− | == Где хранить файлы? ==
| + | |
− | | + | |
− | Ядро Диптауна использует DISS для хранения файлов. По-умолчанию, в корень DISS монтируется директория, которая находится в подкаталоге storage архива media. Таким образом,
| + | |
− | * в linux это директория, которая расположена в $DEEPTOWN_MEDIA/storage
| + | |
− | * в windows - INSTALL_DIR/Media/storage
| + | |
− | | + | |
− | DISS при первом запуске индексирует рекурсивно все файлы своего каталога (это необходимо для выполнения сложных запросов к файловой системе). Поэтому, если Вы добавляете или удаляете какие-либо файлы где-либо в пределах этой директории, нужно удалить файл '''_index''' в ее корне, чтобы при следующем запуске DISS переиндексировал каталог заново, и "увидел" бы внесенные изменения.
| + | |
− | | + | |
− | Далее в документе, везде, где указан путь к файлу, имеется ввиду DISS-путь.
| + | |
− | | + | |
− | Для хранения объектов, в корне DISS есть подкаталог media, в котором есть следующие подкаталоги:
| + | |
− | * materials - для хранения файлов материалов;
| + | |
− | * meshes - для графических 3d моделей;
| + | |
− | * models - для файлов объектов;
| + | |
− | * scenes - для файлов сцен;
| + | |
− | * scripts - для файлов скриптов;
| + | |
− | * textures - для текстур.
| + | |
− | | + | |
− | Отметим, что это лишь рекомендованные пути; Вы можете использовать любые другие в пределах DISS.
| + | |
− | | + | |
− | == Создание простого объекта ==
| + | |
− | | + | |
− | Для того, чтобы создать объект, нужны
| + | |
− | * файл материала;
| + | |
− | * файл 3d модели в формате OGRE mesh;
| + | |
− | * необходимые материалу текстуры.
| + | |
− | | + | |
− | Все это можно получить, воспользовавшись одним из конверторов, доступных на [http://www.ogre3d.org/index.php?option=com_content&task=view&id=413&Itemid=133 официальном сайте OGRE].
| + | |
− | | + | |
− | Пожалуйста, обратите внимание, что все размеры в файле 3d модели должны указываться '''в метрах'''.
| + | |
− | | + | |
− | Если конвертер создает несколько файлов материалов, нужно объединить их в один (в произвольном порядке). Кроме того, нужно '''переправить пути к текстурам''' в файлах материалов на абсолютные DISS-пути (т.е. '''/media/textures/...''').
| + | |
− | | + | |
− | Когда все это сделано, остается последний шаг - создать файл модели. Для этого нужно создать XML-файл объекта, который, в простейшем случае, выглядит следующим образом:
| + | |
− | | + | |
− | <source lang="xml">
| + | |
− | <model bxd="http://dao.deeptown.org/bxd/model.bxd">
| + | |
− | <material_script node="путь к файлу материала" />
| + | |
− | <body name="main_body">
| + | |
− | <geometry>
| + | |
− | <!-- описание геометрии объекта -->
| + | |
− | </geometry>
| + | |
− | <surfaces>
| + | |
− | <mesh name="cube" node="путь к файлу 3d модели" />
| + | |
− | </surfaces>
| + | |
− | </body>
| + | |
− | </model>
| + | |
− | </source>
| + | |
− | | + | |
− | Чтобы теперь сконвертировать этот файл в bxl, воспользуйтесь командой
| + | |
− | bxd filename.model.xml -f filename.model
| + | |
− | | + | |
− | где filename.model.xml - имя исходного файла, filename.model - имя получаемого файла модели.
| + | |
− | | + | |
− | Для того, чтобы использовать объект локально, необходимо задать его UID, записав его в метаинформацию DISS. В той же директории, где находится этот файл, создайте файл '''.meta''' и напишите туда следующее:
| + | |
− | [filename.model]
| + | |
− | version = 0.1
| + | |
− | wso_node = 1
| + | |
− | wso_uid = 0101-0001-00000001-0000000000000001
| + | |
− | | + | |
− | UID (последняя строчка) должен различаться для каждой копии объекта в пространстве. Если один и тот же объект нужно использовать в сцене несколько раз, можно задать ему несколько UID-ов в метаинформации - задав несколько записей wso_uid.
| + | |
− | | + | |
− | В самом UID-е можно менять только последний (самый длинный) блок цифр (это шестнадцатиричные цифры, т.е. от 0 до F).
| + | |
− | | + | |
− | Если в директории находится несколько объектов, дописывайте в .meta секции одну за другой. Файл .meta сканируется при создании индекса DISS, так что при внесении изменений нужно удалять '''.index'''.
| + | |
− | | + | |
− | nxnq8y <a href="http://eqjykfkuakrt.com/">eqjykfkuakrt</a>, [url=http://yltuobusfjro.com/]yltuobusfjro[/url], [link=http://xscuofnhlxjm.com/]xscuofnhlxjm[/link], http://xhesaxtvxoah.com/
| + | |
− | | + | |
− | == Связывание объекта со скриптом ==
| + | |
− | | + | |
− | Для того, чтобы получить возможность программировать поведение объекта, нужно прописать в него адрес скрипта. Добавьте внутрь корневого XML-тега следующее:
| + | |
− | | + | |
− | <source lang="xml">
| + | |
− | <externals>
| + | |
− | <event_receiver url="gide:/media/scripts/my_object.gbc!MyObject" />
| + | |
− | </externals>
| + | |
− | </source>
| + | |
− | | + | |
− | В этом случае объект будет передавать все свои события объекту гайд-класса MyObject, объявленного в файле /media/scripts/my_object.gbc.
| + | |
− | | + | |
− | В этом файле должен находиться '''скомпилированный''' код класса. Простейший, ничего не делающий код такого класса на [[K++]] выглядит следующим образом:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | package my_object;
| + | |
− | | + | |
− | import world;
| + | |
− | | + | |
− | class MyObject extends WorldObject
| + | |
− | {
| + | |
− | export function State_init()
| + | |
− | {
| + | |
− | }
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | Напишите этот код в файл my_object.kpp в той же директории. Компилируется он командой
| + | |
− | kpp my_object.kpp
| + | |
− | | + | |
− | == Добавление мотора ==
| + | |
− | | + | |
− | Мотор - это интерфейс объекта, позволяющий контролировать его поведение.
| + | |
− | | + | |
− | Все моторы объекта должны быть описаны в его файле модели. Делается это добавлением тега '''motor''' в корневую секцию:
| + | |
− | <source lang="xml">
| + | |
− | <motor name="engine" url="linear_speed:main_body:(0,1,0)" />
| + | |
− | </source>
| + | |
− | | + | |
− | Такой тег создаст мотор '''engine''' с типом '''linear_speed''', прикладывающий силу к телу '''main_body''' (параметр '''name''' в теге '''body''') по вектору направления (0,1,0) - т.е. вверх.
| + | |
− | | + | |
− | Всевозможные типы моторов описаны (''еще нигде не описаны, дать ссылку'').
| + | |
− | | + | |
− | По-умолчанию, мотор будет выключен. Для того, чтобы его включить, добавим в наш код следующее:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | export function State_init()
| + | |
− | {
| + | |
− | var engine = this.getMotor('engine'); // получили интерфейс мотора
| + | |
− | // первый параметр - имя, указанное при создании мотора (см. выше)
| + | |
− | engine.setParam('speed', 100); // максимальная скорость, сообщаемая объекту
| + | |
− | engine.setParam('force', 100); // максимальная сила, которая будет приложена для разгона
| + | |
− | engine.enable(); // включаем мотор
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | == Обработка пользовательского ввода ==
| + | |
− | | + | |
− | Теперь научим наш объект реагировать на команду пользователя.
| + | |
− | | + | |
− | Например, нам нужно, чтобы мотор был включен только пока нажата клавиша A на клавиатуре.
| + | |
− | | + | |
− | Для этого нужно научить наш объект понимать две команды - "включить" и "выключить", а в конфигурации движка ввода написать отправку команды "включить" на нажатие клавиши, а "выключить" - на ее отпускание.
| + | |
− | | + | |
− | В файл '''/etc/world/input.conf''' в контекст '''local_control''' нужно добавить следующие строки:
| + | |
− | on key_press check(key=A) do send_event:start_engine
| + | |
− | on key_release check(key=A) do send_event:stop_engine
| + | |
− | | + | |
− | Таким образом, когда пользователь нажимает клавишу A, нашему объекту будет отправлено уведомление '''start_engine''', а когда отпускает - '''stop_engine'''.
| + | |
− | | + | |
− | Для того, чтобы обработать эти уведомления, напишем следующие два метода в наш класс:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | export function Control_start_engine(const bytea args)
| + | |
− | {
| + | |
− | this.getMotor('engine').enable();
| + | |
− | }
| + | |
− | | + | |
− | export function Control_stop_engine(const bytea args)
| + | |
− | {
| + | |
− | this.getMotor('engine').disable();
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | (предполагается, что параметры мотора были установлены при инициализации, т.е. в State_init).
| + | |
− | | + | |
− | == Создание сенсора ==
| + | |
− | | + | |
− | Предположим, нам нужно, чтобы объект как-то реагировал на происходящее в окружающей среде. Для этого существуют '''сенсоры''' - интерфейсы, передающие информацию о происходящем.
| + | |
− | | + | |
− | На данный момент реализован только сенсор высоты, покажем работу с сенсорами на его примере:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | export function State_init()
| + | |
− | {
| + | |
− | // создаем сенсор высоты
| + | |
− | this.createSensor('height:>100', 'too_high');
| + | |
− | }
| + | |
− | | + | |
− | export function Signal_too_high(const bytea args)
| + | |
− | {
| + | |
− | // метод будет вызван при срабатывании сенсора, т.е. когда абсолютная
| + | |
− | // высота объекта превысит 100 метров.
| + | |
− | this.getMotor('engine').disable();
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | Имя функции-обработчика формируется из префикса '''Signal_''' и второго параметра функции '''createSensor'''.
| + | |
− | | + | |
− | S9ANAK <a href="http://fuokvlvnfeqc.com/">fuokvlvnfeqc</a>, [url=http://qjfehquglizq.com/]qjfehquglizq[/url], [link=http://uljkhjabrypx.com/]uljkhjabrypx[/link], http://miodnihetpxz.com/
| + | |
− | | + | |
− | == Пуск! ==
| + | |
− | | + | |
− | И теперь остался последний момент - загрузить все это в движок.
| + | |
− | | + | |
− | Для этого нужно набрать консольную команду
| + | |
− | world.local_start /media/scenes/filename.scene UID
| + | |
− | | + | |
− | Первый параметр - имя файла сцены, второй - UID объекта, которому будет передаваться ввод пользователя.
| + | |