Документация/Статьи/Обзор редактора логики

From NeoAxis Engine Wiki

Jump to: navigation, search
Перейти на уровень выше
Окно редактора логики

Contents

Описание

Редактор логики - это составная часть редактора карт. Редактор логики предназначен для создания специфичных для карты алгоритмов, т.е. таких, которые нужны только на этой карте.

В редакторе можно создавать классы, и определять для них методы и переменные. Методы - это записанные алгоритмы. Причем записывать их можно двумя способами: Designer Type (с помощью пользовательского интерфейса) и Script Type (на языке программирования C#).

Одной из ключевых возможностей редактора, является возможность создавать классы, которые надстраиваются над определенным классом игрового объекта. Данная возможность позволяет создавать обработчики событий игровых классов. Примером использования, может служить надстройка над типом Region. У класса Region есть метод ObjectIn - событие, когда персонаж попадает внутрь области. В редакторе логики, мы можем написать такой алгоритм, что попадая в определенное место на карте, обозначенное объектом Region, впереди игрока обрушивалась балка с потолка.

Запуск редактора логики

Редактор логики запускается непосредственно из редактора карт. Чтобы запустить редактор, нужно открыть карту и затем в меню World нажать кнопку Logic Editor.

Logic2.jpg

Общий вид

Logic3.jpg

Окно редактора логики имеет 4 основных области:

  • 1 - Верхняя панель.
  • 2 - Окно со списком классов.
  • 3 - Рабочее окно.
  • 4 - Окно вывода.

Ознакомимся с каждым элементом подробнее.

Верхняя панель

Logic4.jpg

Верхняя панель состоит из главного меню и пары кнопок для быстрого вызова функций. Опишем основные функции главного меню.

Меню File.

Logic9.jpg
Save Map сохраняет изменения карты.

Меню View.

Logic10.jpg
Настройка вида окна редактора.

Class List делает видимым окно классов.

Output делает видимым окно вывода, если соответствующее окно было закрыто.

Меню Tools.

Logic11.jpg
Run Simulation запускает карту.

Build Test проверяет алгоритмы на синтаксические ошибки.

Окно со списком классов

Logic5.jpg

Окно служит для создания классов логики карты. Здесь вы можете добавлять классы, а к классам добавлять методы и переменные.

Добавление нового класса

Добавление нового класса к логике карты осуществляется по нажатию кнопки Create Class контекстного меню элемента Map Classes в списке Классов.

Logic12.jpg

Предварительно новый класс настраивается в специальном окне.

Logic13.jpg

Помимо имени класса необходимо указать его тип. Класс может быть двух типов:

  • Static. Обычный класс.
  • Entity. Класс, надстраиваемый над одним из классов игровых объектов. В поле Entity Class Type указывается над каким именно классом будет надстраиваться создаваемый класс.

Контекстное меню класса

Работа с классом осуществляется, в основном, через его контекстное меню. Рассмотрим функции доступные для изменения класса.

Logic14.jpg

Edit (изменение). Позволяет сменить имя класса.

Delete (удаление). Позволяет удалить класс.

Create Method (создание метода). Добавляет метод к классу. Можно создать как произвольный пользовательский метод (меню Method), так и надстройку над методом базового Entity-класса. Кроме того, необходимо выбрать способ создания метода: Designer Type или Script Type.

Logic15.jpg

Если добавляется пользовательский метод, то необходимо указать тип возвращаемого функцией значения. Если нет необходимости, чтобы функцию возвращала значение, то указывается тип void. Также при необходимости нужно указывать список входных параметров. Каждый параметр характеризуется именем и типом значения.

Logic17.jpg

Create Variable (создание переменной). Добавляет переменную к классу. Необходимо указать название переменной и ее тип. В качестве типа могут выступать как простые типы, вроде числа или строки, так иодин классы игровых объектов.

Logic16.jpg

Если выставлен флаг Serialization, то значение переменной будет сохраняться при сохранении мира (Load/Save в Game.exe).

Create Custom Script Code. Позволяет присоединять к классу произвольный код, который может содержать методы и объявления переменных. К примеру, Custom Script Code позволяет определять сложные переменные, такие как списки, которые нельзя добавить с помощью меню Create Variable.

Рабочее окно

В рабочем окне записываются алгоритмы карты. Окно имеет различный вид, в зависимости от типа метода.

Неизменно наверху окна находится панель вкладок, с помощью которой можно переключаться между окнами редактирования различных методов.

Чтобы перейти в режим редактирования класса, необходимо щелкнуть по нему левой кнопкой мыши дважды.

Designer Type

Рабочее окно в режиме Designer Type

В режиме Designer Type рабочее окно состоит из двух областей: списка команд Actions и окна редактирования команды.

Designer Type подразумевает создание алгоритмов с помощью пользовательского интерфейса. Для добавления и удаления команд имеются две кнопки над списком Actions.

Logic19.jpg

Также эти и другие функции редактирования доступны из контекстного меню элементов списка команд.

Logic18.jpg

Рассмотрим каждую из этих функций:

  • Insert (вставка). Добавляет новую команду перед текущей. Подробнее о командах в Designer Type написано ниже.
  • Insert (After Current) (вставка после текущего). Добавляет новую команду после выбранной. Доступно только для операторов, подразумевающих использование нескольких команд внутри себя. Это такие операторы как if (условный оператор) и while (цикл).
  • Copy (копирование). Копирует выбранную команду в буфер для последующий вставки.
  • Paste (вставка). Вставляет команду из буфера перед текущей.
  • Delete (удаление). Удаляет выбранную команду из списка.

Команды в Designer Type

Окно добавления команды выглядит следующим образом.

Logic20.jpg

Создание команды проходит рекурсивно. В окне Choose Action выбирается какое-либо действие, для этого по нему нужно сделать двойной щелчок. Далее в том же окне добавленное действие настраивается: выбираются параметры, операторы, свойства. Для настройки вызывается то же самое окно Choose Action. Разница лишь в том, что изменяется список доступных методов - будут предложены лишь те, которые актуальны для добавленной в первом окне команды. Добавленное в новом окне, действие настраивается с помощью того же окна. Окно Choose Action появляется пока не настроена вся команда. Тогда, нажимая на кнопку Ok последовательно во всех открывшихся окнах, мы в итоге возвращаемся к самому первому окну Choose Action, нажимаем в нем Ok и команда появляется в списке.

Окна Choose Action для изменения цвета источника света

Элементы команды, доступные для редактирования, подсвечиваются как гиперссылка.

Logic61.jpg

Основные комнады

Название Описание
Get Entity Получение доступа к игровому объекту. Нажав на [...], можно получить доступ к свойствам объекта.
This Members Переменные-члены класса. Т.е. это те переменые, которые вы создали с помощью функции Create Variable. Кроме того сюда относится переменная Owner, которая ссылается на "хозяина" объекта.
Control Операторы.
  • If/Then/Else. Условный оператор. Если условие после ключевого слова if верно, то выполняется идущие следом команды, иначе выполняются команды идущие после ключевого слова else.
  • While. Оператор цикла. Команды стоящие после оператора, выполняются до тех пор, пока верно условие, указанное после ключевого слова while.
  • Return. Возвращает значение функции. Актуален для пользовательских функций, чей тип отличен от void.
Local Variables Работа с локальными переменными. С помощью команд данного блока можно определить временную переменную (оператор declare) или использовать уже определенную. Кроме того, в этом блоке доступны параметры функции.
Static Members Осуществляет доступ к статичным функциям различных классов.
Comment Добавляет пользовательский комментарий, который может содержать пояснение к команде или командам, облегчающий понимание алгоритма.

Перечисленные выше типы можно назвать главными, т.к. с них начинается запись любой команды. Теперь коснемся остальных действий, которые можно выбрать в окне Choose Action.

Команды для игрового объекта

Использование игрового объекта через GetEntity. Выбрав эту команду и указав игровой объект, далее можно его использовать различным способом.

Название Описание
as Оператор преобразовывает объект в другой класс. Может использоваться, например, при преобразовании объекта класса MapObject в объект класса Character. Такое преобразование должно использоваться вкупе с проверкой, принадлежит ли объект к данному классу с помощью оператора is.
is Оператор возвращает True, если объект принадлежит к заданному классу. К примеру, имеется объект общего для всех объектов карты класса MapObject, но нам требуется узнать, не является ли объект игровым персонажем. Тогда мы воспользуемся оператором is и проверим, не принадлежит ли объект к классу Character.

Кроме того, можно использовать свойства и методы объекта. Для каждого типа объекта определены свои свойства и свои методы.

Условные выражения

Условия используются в операторах If/Then/Else, While, а также могут быть значениями переменных или параметров типа Boolean. Результатом условного выражения является либо истина (True), либо ложь (False).

В качестве условных выражений могут использоваться логические операции. Их можно найти в среди статичных функций типа Boolean. Рассмотрим перечисленные там логические операции.

Операция Описание
Boolean == Boolean Сравнение. Истинно, если аргументы имеют одинаковые значения.
Boolean != Boolean "Не равно". Истинно, если аргументы имеют разные значения.
! Boolean Логическое НЕ. Инвертирует значение аргумента.
Boolean and Boolean Логическое И. Истинно, если истинны оба аргумента.
Boolean or Boolean Логическое ИЛИ. Истинно, если истинен хотя бы один аргумент.

Кроме того, элементами логическими выражения могут различные функции сравнения всевозможных типов. К ним относятся следующие операции.

Операция Описание
== Сравнение. Истинно, если аргументы имеют одинаковые значения.
!= "Не равно". Истинно, если аргументы имеют разные значения.
< Меньше. Истинно, если первый аргумент меньше второго.
> Больше. Истинно, если первый аргумент больше второго.
<= Меньше или равно. Истинно, если первый аргумент меньше или равен второму.
>= Больше или равно. Истинно, если первый аргумент больше или равен второму.

Условный оператор

Logic62.jpg
Условный оператор if\then\else можно найти в списке действий в разделе Control. Общий вид условного оператора:

"if условие then действие1 else действие2"

В поле условие вписываются условные выражения, речь о которых шла в разделе выше. Если условие выполняется, другими словами, условное выражение принимает значение True, то выполняются операторы из блока then (действие1). Если же условие не выполняются, то выполняются операторы из блока else (действие2).

Блок else не обязателен к заполнению. В случае, когда данный блок опущен, условный оператор принимает еще более простой вид:

"if условие then действие"

Оператор цикла

Logic63.jpg
Оператор цикла расположен в свитке Control списка команд. Общий вид оператора цикла:

"while условие действие"

Поле условие должно содержать условное выражение. До тех пор пока оно выполняется, циклично выполняются операторы блока while (действие). Т.е. сначала проверяется условие, если оно верно выполняются следующие за ним операторы. Затем условие опять проверяется и если оно еще верно, то выполняются операторы. И так далее до тех пор, пока условие выполняется.

Необходимо заметить, что с оператором цикла нужно быть осторожным, ведь если условие никогда не будет иметь значение False, то цикл будет бесконечным и не закончит свою работу. Такая ситуация может привести к ошибке.

Математические операции

В редакторе логике вы можете найти множество математических операций. Для таких операций как сложение, вычитание, умножение, деление имеются специальные методы-члены у различных числовых классов. К таким классам относятся:

  • Int32 - целочисленный, знаковый.
  • Single - дробный, знаковый.

Для более сложных операций имеется специальный класс Math. Приведем описание его методов.

Название Описание
DegToRad Функция, переводящая градусы в радианы.
RadToDeg Функция, переводящая радианы в градусы.
Sqrt Функция квадратного корня.
Sin Функция синуса угла, заданного в радианах.
Cos Функция косинуса угла, заданного в радианах.
Tan Функция тангенса угла, заданного в радианах.
ASin Функция арксинуса, возвращающая угол в радианах.
ACos Функция арккосинуса, возвращающая угол в радианах.
ATan Функция арктангенса. Имеется два варианта этой функции.
  • ATan( Single a ) - функция арктангенса, возвращающая угол в радианах.
  • ATan( Single y, Single x ) - возвращает угол в радианах между катетом и гипотенузой, x - длина смежного катета, y - противолежащего.
Pow Функция возведения числа в степень, где первый аргумент - основание, а второй - степень.
Exp Функция возвращает значение экспоненты (e), возведенной в степень аргумента.
Floor Функция возвращает наибольшее целое число, меньшее или равное по значению числу или выражению, заданного аргументом.
Log Функция логарифма. Имеется два варианта этой функции.
  • Log( Single a ) - функция натурального логарифма (по основанию e).
  • Log ( Single a, Single newBase ) - функция логарифма, где newBase - основание.
Log10 Функция десятичного логарифма.

Базовые методы

В данном разделе будут приведены основные операции, которые могут вам понадобиться при создании логики карты.

Далее будут представлены статические классы и описания их членов. Все эти классы находятся в свитке Static Members списка команд.

Класс Entities.

Название Описание
Create Создание игрового объекта. Имеется два варианта этой функции:
  • Create( EntityType type, Entity parent )
  • Create( String type, Entity parent )

Отличаются эти функции лишь способом передачи типа объекта: с помощью класса EntityType, или с помощью строки с именем типа. Второй параметр parent должен содержать в себе владельца игрового объекта. Для объктов на базе MapObject, родителем всегда будет Map.Instance.

GetByName Получение игрового объекта по имени. После этой команды можно использовать оператор as или is, о которых написано здесь.
GetUniqueName Генерирует уникальное имя для игрового объекта.
TickDelta Промежуток времени между тиками в секундах. Каждый тик происходит обновление всех систем движка (игровых объектов, устройств ввода). По умолчанию в секунду производится 30 тиков, т.е. TickDelta будет равен 1/30 секунды.

Класс EnityTypes.

Название Описание
GetByName Получение типа игрового объекта по имени.

Класс Logic.

Название Описание
Wait Ожидание. Выполнение, следующих за этим оператором команд, приостанавливается на указанное время. Движок, при этом, продолжает свою работу.

Пример: мигающий источник света. Мы можем включать\выключать источник света в цикле, вызывая функцию Wait в каждой итерации. При этом задержка не будет сказываться на игре: задержка не отразится на взаимодействии остальных объектов, игрок сможет управлять своим персонажем.

Script Type

Рабочее окно в режиме Script Type

В режиме Script Type рабочее окно - это текстовый редактор с подсветкой синтаксиса, в котором пишется исходный код метода на языке C#.

Этот режим весьма удобен для программистов. Написание кода в режиме Script Type немногим отличается от написания кода проекта в среде программирования (например, в Visual Studio).

Компилирование кода осуществляется на этапе запуска карты. Кроме того, можно проверить код на ошибки, нажав кнопку Build Test.

Окно вывода

Logic8.jpg

В окне вывода собираются ошибки и предупреждения, выявленные редактором после тестовой сборки логики.

Добавление логики к объектам карты

Основными элементами логики карты являются надстраиваемые классы. Чтобы добавить логику к объекту карты, необходимо указать логический класс объекта. За это отвечает параметр Logic Class.

Logic21.jpg

На выбор в качестве логического класса объекта, предоставляется список классов логики карты доступных для этого объекта. Разумеется, доступны лишь те классы, которые основаны на тех же классах, что и класс самого объекта.

Logic22.jpg

Урок - Designer Type

В этом уроке мы познакомимся с созданием логики карты в режиме Designer Type. Настроим логику так, чтобы при попадании главного персонаж в регион, загорался источник света, а при выходе из региона - гас.

Для теста логики нам понадобится карта состоящая из шести объектов:

  • Ландшафт (HeightmapTerrain).
  • Небо (SkyDome).
  • Directional-источник света (Light).
  • Точка старта (SpawnPoint).
  • Регион (Region).
  • Spot-источник света (Light).
Карта для теста логики
О том, как создавать карты можно прочитать в этом уроке.

Главным образом, из всех объектов карты нас интересуют два: регион и spot-источник света. К ним и будет применена логика карты.

Начнем с того, что запустим редактор логики. Нажмите кнопку Logic Editor в меню World.

Logic24.jpg

Главная наша задача - сделать надстройку над классом Region. Добавим соответствующий класс. Для этого нажмем правой кнопкой на элементе Map Classes списка Class List и в появившемся меню нажмем кнопку Create Class.

Logic25.jpg

В окне создания класса укажем имя класса (например, Region_0), тип - надстраиваемый класс (Entity) и базовый класс - Region. После этого нажмем кнопку Ok.

Logic26.jpg

Наш класс добавлен в список классов. Следующий шаг - добавление методов к классу. Начнем с метода, отвечающего за появление персонажа в регионе. Нажмем правой кнопкой на наш класс, выберем пункт Create Method. Среди методов выберем ObjectIn (именно он вызывается при попадании персонажа в регион). И, наконец, выберем способ создания метода: Designer Type.

Logic27.jpg

Теперь заставим наш метод включать источник света. Добавим команду, нажав на кнопку Insert над списком Actions.

Logic28.jpg

Чтобы получить доступ к источнику света, нам понадобится функция GetEntity. Кликните по ней дважды.

Logic29.jpg

В качестве параметра у GetEntity значится null. Изменим параметр, кликнув по нему.

Logic30.jpg

Нужный нам объект - spot-источник, который в нашем случае называется Light_0.

Logic31.jpg

Теперь обратимся к свойству DiffuseColor нашего источника света. Для этого нужно кликнуть по надписи [...].

Logic32.jpg

Дважды щелкнем по DiffuseColor в списке.

Logic33.jpg

Теперь присвоим цвету источника значение. Начнем с оператора присваивания. Кликнем по [...].

Logic34.jpg

И выберем оператор =, дважды кликнув по нему.

Logic35.jpg

Осталось указать присваиваемое значение. Нажмем на аргумент null.

Logic36.jpg

Цвет источника - это значение типа ColorValue. Чтобы создать новое значение данного типа, обратимся к списку Static Members, в котором выберем тип ColorValue. Теперь дважды щелкнем на одноименной функции (нас интересует вариант с тремя параметрами: r, g и b).

Logic37.jpg

При попадании главного персонажа источник должен гореть ярко, а значит его цвет должен быть белым. Т.е. каждая компонента его цвета будет равна 1. Нажмем на первый параметр null.

Logic38.jpg

Дважды кликнем по элементу Constant. Нам будет предложено значение по умолчанию, равное нулю. Нажмем на него, чтобы изменить на единицу.

Logic39.jpg

Проделаем то же самое с остальными двумя компонентами цвета. После этого нажмем на кнопку Ok.

Logic40.jpg

Во всех остальных окнах также нажмем Ok и увидим получившуюся команду.

Logic41.jpg

С событием, связанным с попаданием главного персонажа в регион, мы закончили. Теперь нужно проделать все те же операции, но для обратного события - выхода главного персонажа из региона. Функция, вызываемая при этом событии, называется ObjectOut. Кроме того, свет мы будем тушить, а значит компоненты цвета источника будут равны нулю.

Logic42.jpg

Не забудем сохранить карту вместе с ее логикой.

Logic43.jpg

Теперь перейдем в окно редактора карт, чтобы добавить, созданный нами, логический класс к региону. Выделим регион на карте и укажем его параметр LogicClass.

Logic44.jpg

Выберем класс Region_0 в предлагаемом списке и нажмем кнопку Ok.

Logic45.jpg

Последний шаг - это небольшая мелочь, без которой не получилось бы увидеть зажигание света при попадании в регион. Необходимо выключить наш источник, т.е. сделать его цвет черным, чтобы заметить изменение цвета при срабатывании события.

Logic46.jpg

Запустим карту в режиме симуляции, чтобы посмотреть, что у нас получилось.

Logic47.jpg

При попадании главного персонажа в регион, свет загорается. И гаснет, когда персонаж из региона выходит. А значит логика карты работает!

Персонаж вне региона Персонаж внутри региона

Урок - Script Type

В этом уроке мы опробуем возможности скриптового режима редактора логики. Для демонстрации возможностей будем использовать ту же карту, что и в предыдущем уроке. Как и в предыдущий раз, мы будем использовать события попадания и выхода главного персонажа в регион. Но на этот раз, заставим источник света плавно менять свой цвет.

Начнем с того, что добавим класс, надстраиваемый над объектом типа регион. Нажмем правой кнопкой на элемент Map Classes и выберем пункт Create Class.

Logic50.jpg

В появившемся окне укажем имя класса, тип и класс, над которым будет произведена надстройка. Назовем класс Region_0. Т.к. нас интересует надстраиваемый класс, то в качестве типа выберем Entity. А классом для надстройки выберем Region.

Logic51.jpg

Для управления источником света, нам понадобится следить за тем, находится персонаж в регионе или нет. Заведем соответствующую переменную. Нажмем правой кнопкой на класс Region_0 и выберем пункт Create Variable.

Logic52.jpg

Зададим тип переменной - Boolean (логический тип, имеющий два значения: True (истина) и False (ложь)). А также укажем имя переменной - characterInRegion.

Logic53.jpg

Переменная создана. А значит нужно добавить контроль ее значения. При попадании персонажа в регион, вызывается событие ObjectIn. Добавим соответствующую функцию к классу Region_0. Нажмем правой кнопкой на класс и выберем меню Create Method. Затем выберем событие ObjectIn и способ записи алгоритма - Script Type.

Logic54.jpg

При попадании персонажа в регион, необходимо менять значение нашей переменной characterInRegion на значение True. В рабочем окне напишем следующий код:

characterInRegion = true;

Теперь нам необходимо отследить обратное событие - выход персонажа из региона. В нем мы должны поменять значение нашей переменной на значение False, а также потушить наш источник света. Добавим функцию ObjectOut к классу Region_0 и напишем в рабочем окне следующий код.

characterInRegion = false;
((Light) Entities.Instance.GetByName( "Light_0" )).DiffuseColor = new ColorValue(0, 0, 0);

А сейчас к перейдем самому интересному! Будем каждый кадр тик менять цвет источника света. Если персонаж находится внутри региона, то заставим источник плавно менять свой цвет с зеленого на красный. Событие, вызываемое каждый тик - это метод Tick. Добавим его к нашему классу Region_0. Ниже приведен код метода.

if(characterInRegion)
{
	float t = (((int)(EngineApp.Instance.Time * 1000)) % 3000) / 3000.0f;
	float r = -4 * t * t + 4 * t;
	float g =  4 * t * t - 4 * t + 1;
	((Light) Entities.Instance.GetByName( "Light_0" )).DiffuseColor = new ColorValue(r, g, 0);
}

Цвет источника меняется циклично. Число 3000 здесь - это период смены цвета в миллисекундах.

Сохраним логику карты через меню File -> Save Map.

Logic56.jpg

Нам осталось лишь задать логический класс для объекта регион. Для этого перейдем в редактор карт, выделим регион и укажем ему параметр LogicClass.

Logic57.jpg

В появившемся окне выберем класс Region_0 и нажмем кнопку Ok.

Logic58.jpg

Запустим нашу карту в режиме симуляции.

Logic47.jpg

Зайдя в область региона, увидим, что источник света начинает плавно менять свой цвет.

Источник света горит красным цветом