Программирование поведения объекта — различия между версиями

Материал из Deeptown Manual
Перейти к: навигация, поиск
(Создание сцены)
(aiZESWjKPEVlFJUKfCC)
Строка 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 объекта, которому будет передаваться ввод пользователя.
+

Версия 00:25, 12 сентября 2012

DuNaVB <a href="http://slnlfzsbnlhd.com/">slnlfzsbnlhd</a>, [url=http://ngbwkywvrjrn.com/]ngbwkywvrjrn[/url], [link=http://whabeeastqrh.com/]whabeeastqrh[/link], http://ihpwqajwapmy.com/

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
информация
документация
Инструменты