Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Вклады
                MonkeyBrains - Мозги Обезьяны

MonkeyBrains — Мозги Обезьяны

Опубликованно: 20.04.2018, 20:32
Последняя редакция, Andry: 10.05.2018 11:10

Добро пожаловать в MonkeyBrains вики!

  • С чего начать
  • Простое поведение
  • Реализация Пользовательского оружия
  • Реализация системы Очков Здоровья
  • Реализация системы Инвенторя
  • Система Событий в MonkeyBrains
  • Реализация Пользовательский control-ов для игры

С чего начать

  • Скачайте MonkeyBrains отсюда github.
  • Откройте его как проект в jMonkeyEngine SDK
  • Если не будут найдены библиотеки то добавьте библиотеку jme3-core.
  • В свойствах проекта в пункте Исходные файлы напротив Формат исходного/бинарного файла выберите JDK 8 или выше.
  • Далее очистите и соберите проект
  • Теперь в папке проекта dist появится файл MonkeyBrains.jar
  • Добавить его в свой проект в качестве библиотеки, и можете пользоваться.
  • Есть вероятность того что вам потребуется что то обновить так как он создавался при более ранней версии движка, нежели нынешняя.

Также следует знать что для не релизной версии, а версии в разработке данная статья устарела так как автор внёс некоторые существенные изменения в свой проект не исправив документацию и не обновив примеры. По сути она не закончена и я бы не рекомендовал её использовать новичкам. Вот его разъяснение:

Я сделал некоторые коммиты MonkeyBrains: переместил некоторые вещи в другой пакет (monkeystuff) и лишил агентов некоторых функций.

Старая функциональность сохраняется в новых BluePillAgents. Я назвал их таким образом, потому что я думаю, что это передает мое намерение: «Голубая Таблетка»(Blue Pill) — обычный способ, он хорошо документированы в вики, и он должны работать с текущими примерами.

Поскольку есть «Голубая Таблетка», будет также «Красная Таблетка»(Red Pill), которая будет немного отличаться. Я не являюсь экспертом в области ИИ, я просто хочу приключений в этом аспекте:

«Красная Таблетка» будет построена вокруг потребностей моей игры, так что да, я на самом деле буду есть свою собачью еду (обезьянью еду?).

Основные понятия:

Свой класс Агента вы наследуете от класса Agent. Он содержит атрибуты и операции над этими атрибутами. Их не рекомендуется изменять(расширять) при наследовании. Вместо расширения вы можете использовать метод setModel(T model) и задать свои настраиваемые атрибуты для агента.

Behavior Базовый класс для поведения агента. Каждое создаваемое поведение должно расширить этот класс. Каждое поведение затем должно реализовывать controlUpdate(float tpf). Те будет запрашивается com.jme3.scene.control.AbstractControl, который был расширен поведением(behavior). Также класс, который расширяет Behavior, должен иметь конструктор, который будет содержать агента в качестве параметра. При этом behavior(поведение) может изменять атрибуты агента, которые являются behavior(поведением). В com.jme3.ai.agents.behaviors.npc вы можете увидеть примеры некоторых простых видов поведения, которые легко использовать для ваших агентов NPC (Не персонажа Игрока). В com.jme3.ai.agents.behaviors.player есть некоторые примеры простого поведения, достаточные что бы поиграться с агентами.

Класс GameEntity нужен для всех сущностей в игре, которые имеют некоторое отношение к агентам. Примером может быть: Предметы, пули, препятствия, другие агенты (класс Agent расширяет GameEntities) …

MonkeyBrainsAppState Единственный класс, который содержит все игровые объекты и обновляет их. Он создан для упрощения манипуляций с агентами.

Пример:

public class Example extends SimpleApplication {

    //определение игры
    private MonkeyBrainsAppState brainsAppState = MonkeyBrainsAppState.getInstance(); 
    
    public static void main(String[] args) {
        Example app = new Example();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        //определение app
        brainsAppState.setApp(this);

        //инициализация агентов с их именами и spatial-ами
        Agent agent = new Agent("First agent", createAgentSpatial()); 
        //в фреймворке нет такого метода как createAgentSpatial()
        //предполагается что пользователь должен сам создавать свой spatial для игры

        //добавление агента в MonkeyBrainsAppState
        brainsAppState.addAgent(agent);

        //настройте moveSpeed(скоротьДвижения), rotationSpeed(скорость поворота), mass(вес)..
        agent.setMoveSpeed(20); 
        agent.setRotationSpeed(30);
        //используйте для управления поведения из com.jme3.ai.agents.behaviors.npc.steering
        agent.setMass(40);
        agent.setMaxForce(3);

        //создание основного поведения
        //агент может иметь только одно поведение, но это поведение может содержать другое поведение
        agent.setMainBehavior(new MyCustomBehavior(agent));

        //старт агентов
        brainsAppState.start();

    }

    @Override
    public void simpleUpdate(float tpf) {
        brainsAppState.update(tpf);
    }
}

Простое поведение

Простым поведением являются некоторые общие поведения, поддерживаемые MonkeyBrains.

SimpleMainBehavior — основное общее поведение для агентов. Основное поведение содержит другие поведения, и если оно активно, он обновит все разрешенные поведения. Вы можете добавить только одно управление поведением к этому контейнеру. Но вы можете использовать CompoundSteeringBehavior, чтобы объединить больше управлений поведениями в одно.

Пример:

Agent agent = new Agent("SimpleMain", createAgentSpatial());
SimpleMainBehavior mainBehavior = new SimpleMainBehavior(agent);
mainBehavior.addBehavior(new MyCustomBehavior1(agent));
mainBehavior.addBehavior(new MyCustomBehavior2(agent));
agent.setMainBehavior(mainBehavior);

SimpleMoveBehavior — это общее поведение перемещений для агентов. Агент должен перейти в намеченное положение или по moveDirection(направлению Движения). Если оба будут добавлены, то тогда агент переместится в намеченное положение. Предупреждение: иногда Агент никогда не будет двигаться точно в намеченное положение, если moveSpeed(скорость Движения) слишком высока, поэтому добавьте соответствующую ошибку расстояния. Вместо этого рекомендуется использовать управление поведениями(steering behaviors).

SimpleRotateBehavior — это общее поведение вращения. Если spatial не добавлен, то будут вращать все spatial-ы агентов. Если spatial был добавлен, то будет вращаться только этот spatial.

SimpleLookBehavior — это общее поведения зрения(взгляда) для агентов. Он требуется, для всех поведений в которые добавят слушатели. Это поведение может видеть только GameEntity(Игровые Сущности), если оно добавлено в MonkeyBrainsAppState. Чтобы правильно настроить это поведение, вам необходимо задать следующие параметры:

/**
 * Диапазон видимости. Как далеко может видеть агент.
 */
float visibilityRange;
/**
 * Угол, в котором будут видны GameEntities.
 */
float viewAngle;

Если эти параметры не заданы, тогда поведение зрения никогда не сообщит, что оно что-то увидело. Также необходимо добавить поведение, которое реализовано интерфейсом GameEntitySeenListener. (подробнее см. здесь).

Существует необязательный параметр:

   /**
     * Какие сущности будут сообщать поведению увиденное.
     */
    protected TypeOfWatching typeOfWatching;

    public static enum TypeOfWatching {

        /**
         * Зрение только для агентов.
         */
        AGENT_WATCHING,
        /**
         * Зрение только для игровых сущностей.
         */
        GAME_ENTITY_WATCHING,
        /**
         * Зрение для агентов и игровых сущностей.
         */
        WATCH_EVERYTHING;
    }

Вы можете изменить WATCH_EVERYTHING идущий по умолчанию, чтобы сообщалось только то, что вам нужно.

SimpleAttackBehavior — это общее поведение атаки для агентов. Это поведение агента для атаки targetEntity(намеченнойСущности) или фиксированной точки в пространстве. Он будет атаковать с оружием, и он не проверяет, есть ли у него боеприпасы. Оно реализует GameEntitySeenListener. Если не задана targetedEntity ни фиксированная точка в пространстве, поведение не будет активировано.

Простые поведения игрока реализованы здесь 2 поведениями для играбельности агента в MonkeyBrains.

SimplePlayerMoveBehavior — это общее поведение перемещения для агента, контролируемого игроком. Оно поддерживает AnalogListener. Вы должны добавить для него поведение и соответствующее имя при его использовании (оно должно быть таким же, как и в InputManager).

SimplePlayerAttackBehavior — это общая атака для агента, контролируемого игроком. Он поддерживает ActionListener. Он атакует огнём пуль в направлении щелчка мыши.

Реализация Пользовательского оружия

Оружие — самое важное в играх шутерах, поэтому MonkeyBrains позволяет легко реализовать пользовательское оружие, и оно хорошо интегрируется в фреймвор.

Основные понятия:

AbstractWeapon — абстрактный класс являющийся базовым классом для определения всего оружия, используемого агентами. Он расширяет GameEntity, поэтому вы можете использовать его как элемент, который вы можете найти на карте. Некоторые важные параметры для оружия:

/**
 * Название оружия.
 */
protected String name;
/**
 * Имя агента, к которому добавлено оружие.
 */
protected Agent agent;
/**
 * Максимальный диапазон оружия.
 */
protected float maxAttackRange;
/**
 * Минимальный диапазон оружия.
 */
protected float minAttackRange = 0;
/**
 * Урон от атаки оружием.
 */
protected float attackDamage;
/**
 * Сколько времени потребуется ждать для следующей атаки.
 */
protected float cooldown;

Методы, которые необходимо реализовать:

public abstract void attack(Vector3f targetPosition, float tpf);

/**
 * Метод для вычислений, если для оружия было выполнено требования
 * быть использованным. (Есть ли боеприпасы и.т.п.)
 *
 *Примечание: Не делайте проверку перезарядки, она уже проверяется этим фреймворком.
 *
 * @return true если используется, false в противном случае
 */
public abstract boolean isUsable();

/**
 * Метод для проверки есть ли здесь неограниченного использования оружия.
 *
 * @return true - неограниченное использование, false в противном случае
 */
protected abstract boolean isUnlimitedUse();

/**
 * Метод для уменьшения характеристик от оружия после использования. (патроны, мана, хп и.т.п.)
 */
protected abstract void useWeapon();

Поскольку в классе Agent нет слотов для оружия. Вам нужно будет реализовать Inventory(инвентарь) и поместить оружие внутри него. Не забудьте поместить все методы обновления оружия в метод обновления инвентаря. Если вы этого не сделаете, перезарядка оружия никогда не закончится.

AbstractBulletBasedWeapon — это абстрактный класс для оружия, который стреляет какой-то разновидностью пуль. Он имеет еще один параметр, и это AbstractBullet. Рекомендуется клонировать этои пули для целей оптимизации. Вместо поведения атаки вам необходимо реализовать:

/**
 * Настраиваем пулю, которая должна быть выпущена и придаем ей начальную скорость.
 *
 * @param направление
 * @param tpf
 * @return
 */
protected abstract AbstractBullet controlAttack(Vector3f direction, float tpf);

Поведение атаки уменьшит количество боеприпасов, сбросит перезарядку и добавит пулю в MonkeyAppState для обновления.

AbstractBullet — это базовый абстрактный класс для пуль в игре. Он также расширяет GameEntity. У него есть только один параметр, и это оружие, из которого им стреляли.

AbstractFirearmWeapon — это абстрактное оружие, которое имеет параметр numberOfBullets и имеет реализацию для всех методов, за исключением метода controlAttack(…).

AbstractEnergyWeapon аналогичен AbstractFirearmWeapon, за исключением того, что он имеет параметры:

/**
 * Количество энергии, необходимое для зарядки оружия. Установите значение -1, если бесконечно.
 */
protected int energyRequired;
/**
 * Источник энергии, который питает оружие.
 */
protected AbstractPowerSource powerSource;

AbstractPowerSource — это интерфейс для источника питания, используемого для AbstractEnergyWeapon. Он имеет методы:

/**
 * @param energyRequest(ТребуемаяЭнергия)
 * @return true если источник питания содержит в себе достаточно энергии.
 */
public boolean contains(int energyRequest);

/**
 * Уменьшая количество мощности в источнике питания.
 *
 * @param energyRequest(ТребуемаяЭнергия)
 */
public void consume(int energyRequest);

Реализация системы Очков Здоровья или Hit Points(Implementing Hit Points system)

Фреймворк MonkeyBrains обеспечивает гибкую реализацию системы очков здоровья. Это означает, что программист может реализовать, столько игровых сущностей сколько будут иметь очки здоровья (очки жизни, очки энергии…) и как управлять им.

Основные понятия

HitPoints — это интерфейс для реализации вашего собственного объекта HitPoints для вашей игровой сущности. Методы, которые должны быть реализованы:

/**
 * @return текущие очки здоровья игровой сущности.
 */
public float getCurrentHitPoints();

/**
 * @return максимальное значение очков здоровья для игровой сущности.
 */
public float getMaxHitPoints();

/**
 * Метод уменьшения очков здоровья.
 * @param damage(ущерб)
 */
public void decreaseHitPoints(double damage);

Каждая игровая сущность, которая должна быть уничтожена, должна иметь реализацию HitPoints.

SimpleAgentHitPoints — это класс, который реализует HitPoints. Он реализован для агентов.

HitPointsControl — это интерфейс для игровой сущности цели которая потеряет свои очки здоровья. Он реализует только один метод:

/**
     * Уменьшение hitPoints сущности цели на величину ущерба причинённого 
     * атакующей сущностью.
     *
     * @param target(цель)
     * @param damage(ущерб)
     */
    public void decreaseHitPoints(GameEntity target, float damage);

Пример:

MonkeyBrainsAppState.getInstance().setHitPointsControl(new MyCustomHitPointsControl());
Agent target = new Agent("target", createAgentSpatial());
target.setHitPoints(new SimpleAgentHitPoints(agent));
//уменьшение очков здоровья цели на 30f
MonkeyBrainsAppState.getInstance().decreaseHitPoints(target, 30f);

Реализация системы Инвентаря(Implementing Inventory system)

Фреймворк MonkeyBrains обеспечивает гибкую реализацию системы инвентаризации. Это означает, что программист может реализовать, как будут храниться оружие, предметы и подобные вещи.

Inventory — это интерфейс для реализации инвентаря (дух :)). Он содержит три метода:

/**
 * Метод для обновления все предметов инвентаря, таких как оружие и.т.п.
 *
 * @param tpf время на кадр
 */
public void update(float tpf);

/**
 * Возвращает общую массу инвентаря. Используется главным образом для управления поведением.
 *
 * @return
 */
public float getInventoryMass();

/**
 * Возвращает активное оружие. Это необходимо реализовать, если вы используете
 * SimpleAttackBehavior.
 *
 * @see SimpleAttackBehavior
 * @return
 */
public AbstractWeapon getActiveWeapon();

Пример:

Agent agent = new Agent("AgentWithInventory", createAgentSpatial());
agent.setInventory(new MyCustomInventory());

Система Событий в MonkeyBrains(Event system in MonkeyBrains)

MonkeyBrains поддерживает программирование на основе событий. Если агент видит что-то, то тогда GameEntitySeenEvent будет активирован, если он будет атакован, то будет активирован AgentHitEvent и.т.д. MonkeyBrains реализовал только основные события, и программист должен расширять этот список для своих нужд.

Основные понятия:

GameEntityEvent — это базовое событие для всех событий игровых сущностей. Рекомендуется расширять этот класс для всех ваших пользовательских событий.

GameEntitySeenEvent — это событие, связанное со всеми увиденными игровыми сущностями. Он используется в SimpleLookBehavior.

GameEntitySeenListener — это интерфейс для слушателей события GameEntitySeenEvent. Нет никакого слушателя по умолчанию, предоставленного MonkeyBrains, и настоятельно рекомендуется использовать EventListener в качестве базового интерфейса для слушателей.

Пример: Сделаем пользовательское события игровой сущности:

public class MyCustomGameEntityEvent extends GameEntityEvent {
    private GameEntity customEntity;
    
    public MyCustomGameEntityEvent(Object source, GameEntity gameEntity) {
        super(source);
        this.customEntity = gameEntity;
    }

    public GameEntity getCustomEntity() {
        return customEntity;
    }
}

Сделаем пользовательский слушатель:

public interface MyCustomGameEntityListener extends EventListener {
    public void handleMyCustomGameEntityEvent(MyCustomGameEntityEvent event);
}

Сделаем триггер поведения:

public class TriggerBehavior extends Behavior{
    private List<MyCustomGameEntityListener> listeners;

    public TriggerBehavior(Agent agent){
        super(agent);
        listeners = new ArrayList<MyCustomGameEntityListener>();
    }
    
    public void addListener(MyCustomGameEntityListener listener){
        listener.add(listener);
    }

    @Override
    protected void controlUpdate(float tpf) {
        ...
        //создадим MyCustomGameEntityEvent
        MyCustomGameEntityEvent event = new MyCustomGameEntityEvent(agent, customEntity);
        //перешлите его всем слушателям
        for (MyCustomGameEntityListener listener : listeners) {
            listener.handleMyCustomGameEntityEvent(event);
        }
    }    
}

Сделаем обработку поведения:

public class HandleBehavior extends Behavior implements MyCustomGameEntityListener{

    public HandleBehavior(Agent agent) {
        super(agent);
    }

    public void handleMyCustomGameEntityEvent(MyCustomGameEntityEvent event) {
        //сделайте что-нибудь с этим событием
    }

    @Override
    protected void controlUpdate(float tpf) {
        //код который обрабатывает поведение, обычно в игровом цикле
    }
}

Реализации основной логики:

Agent agent = new Agent("EventAgent", createAgentSpatial());
SimpleMainBehavior mainBehavior = new SimpleMainBehavior(agent);
TriggerBehavior triggerBehavior = new TriggerBehavior(agent);
HandleBehavior handleBehavior = new HandleBehavior(agent);
triggerBehavior.addListner(handleBehavior);
mainBehavior.addBehavior(triggerBehavior);
mainBehavior.addBehavior(handleBehavior);
agent.setMainBehavior(mainBehavior);

С помощью этого кода мы создали агент, который активирует определенное поведение, когда выполняются некоторые условия внутри него.

Реализация Пользовательский control-ов для игры

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

GameControl — это интерфейс для игровых Control-ов, используемых в игре. Методы, которые необходимо выполнить:

/**
 * Добавить все inputManagerMapping которые будет использовать игроком.
 */
public void setInputManagerMapping();

/**
 * Добавить все настройки камеры, которые будут использоваться в игре.
 * @param cam 
 */
public void setCameraSettings(Camera cam);

/**
 * Добавьте все настройки fly camera(летающей камеры), которые будут использоваться в игре.
 * @param flyCam 
 */
public void setFlyCameraSettings(FlyByCamera flyCam);

/**
 * Метод для маркироваки конца. Должен так же останавливать игру.
 * @see Game#stop() 
 * @return 
 */
public boolean finish();

/**
 * Вычисление, выиграл ли агент игру.
 * @param agent
 * @return 
 */
public boolean win(Agent agent);

/**
 * Перезапуск всех параметров игры.
 */
public void restart();   

/**
 * Метод создания сущностей в заданной области.
 * @param gameEntity сущность, которая должна быть создана
 * @param область, в которой будет создана сущность
 */
public void spawn(GameEntity gameEntity, Vector3f... area);

Пример:

MonkeyBrainsAppState.getInstance().setGameControl(new MyCustomGameControl());

Смотрите так же:


Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.