Вниз  [WIP] Fenyx Engine
Всего голосов: 18
- 20.02.2015 / 14:51
DominaN
  Пользователь

DominaN 
Сейчас: Offline
пока что концепция такова - у нас каждый фрейм для всех AI выполняется функция runAI, которая выполняет текущую задачу и если она выполнена или же возникли отклонения от условий выполнения - прерывает ее и меняет на следующую. При этом за задачу и условия отвечают классы AFTTask и AFTCondition, соответственно. AFTTask содержит два основных метода - init() и update(), а также два листа с AFTContition - один содержит набор для выбора задачи, а другой - для прерывания. AFTCondition в свою очередь содержит метод boolean satisfied(), в котором собственно и задается условие успешного выполнения. Если все кондишены из листа choose_conditions в AFTTask возвращают true из метода satisfied, и при этом все кондишены из листа interrupt_conditions возвращают false, то мы можем смело назначать актору этот task.
- 20.02.2015 / 14:56
Dinisimys
  Пользователь

Dinisimys 
Сейчас: Offline
Такой вопрос: погода есть ? если да, то как ее увидеть(включить).
- 20.02.2015 / 14:58
DominaN
  Пользователь

DominaN 
Сейчас: Offline
Dinisimys, пока нету, ну то есть как, в коде она есть, а включить нельзя. Я буду ее переделывать - день и ночь переводить на динамическое освещение, по-любому, а с дождем и снегом я прям хз, вид-то теперь сверху
- 20.02.2015 / 15:30
DominaN
  Пользователь

DominaN 
Сейчас: Offline
В принципе, прототип системы AI работает, но скажите, удобно-ли вам было бы программировать его примерно в таком виде:
  1. public void initAI() {
  2.     //Tasks
  3.     task_idle = new AFTTask() {
  4.  
  5.         public void init() {
  6.             current_speed.reset();
  7.             model.setAnimation(anim_stay, 2);
  8.         }
  9.  
  10.         public void update() {
  11.             angle = AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX());
  12.             rotateObject(angle);
  13.         }
  14.  
  15.         public boolean done() {
  16.             return true;
  17.         }
  18.     };
  19.  
  20.     task_idle.setNextUpdate(0.01f);
  21.     task_idle.addCondition(new AFTCondition() {
  22.  
  23.         public boolean satisfied() {
  24.             return !AFTRuntime.keyPressed(AFTControllable.KEY_ANY);
  25.         }
  26.     });
  27.     task_idle.addInterrupt(new AFTCondition() {
  28.  
  29.         public boolean satisfied() {
  30.             return AFTRuntime.keyPressed(AFTControllable.KEY_ANY);
  31.         }
  32.     });
  33.  
  34.     setTask(task_idle);
  35. }

?
- 21.02.2015 / 17:20
DominaN
  Пользователь

DominaN 
Сейчас: Offline
В общем на данный момент полностью переписанный AI игрока выглядит так:
  1. public void initAI() {
  2.     //Conditions
  3.     AFTCondition cond_walk = new AFTCondition() {
  4.         public boolean satisfied() {
  5.             return AFTRuntime.keyPressed(AFTControllable.MOVE_FORWARD);
  6.         }
  7.     };
  8.     AFTCondition cond_run = new AFTCondition() {
  9.         public boolean satisfied() {
  10.             return (AFTRuntime.keyPressed(AFTControllable.MOVE_FORWARD) && AFTRuntime.keyPressed(AFTControllable.SPRINT));
  11.         }
  12.     };
  13.     //Tasks
  14.     //Idle
  15.     task_idle = new AFTTask() {
  16.  
  17.         public void init() {
  18.             current_speed.reset();
  19.             model.setAnimation(anim_stay, 2);
  20.         }
  21.  
  22.         public void update() {
  23.             rotateObject(AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX()));
  24.         }
  25.     };
  26.  
  27.     task_idle.setNextUpdate(0.01f);
  28.     task_idle.addCondition(new AFTCondition() {
  29.  
  30.         public boolean satisfied() {
  31.             return !AFTRuntime.keyPressed(AFTControllable.KEY_ANY);
  32.         }
  33.     });
  34.     task_idle.addInterrupt(cond_walk);
  35.     task_idle.addInterrupt(cond_run);
  36.  
  37.     //Walk
  38.     task_walk = new AFTTask() {
  39.  
  40.         public void init() {
  41.             model.setAnimation(anim_walk);
  42.         }
  43.  
  44.         public void update() {
  45.             rotateObject(AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX()));
  46.  
  47.             current_speed.x = speed * AFTMathUtils.cos(angle);
  48.             current_speed.y = speed * AFTMathUtils.sin(angle);
  49.  
  50.             model.getCurrentAnimation().setFps((float) (current_speed.length() * 5));
  51.             moveObject(current_speed);
  52.         }
  53.     };
  54.  
  55.     task_walk.setNextUpdate(0.01f);
  56.     task_walk.addCondition(cond_walk);
  57.     task_walk.addInterrupt(cond_walk.invert());
  58.     task_walk.addInterrupt(cond_run);
  59.  
  60.     //Run
  61.     task_run = new AFTTask() {
  62.  
  63.         public void init() {
  64.             model.setAnimation(anim_walk);
  65.         }
  66.  
  67.         public void update() {
  68.             rotateObject(AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX()));
  69.  
  70.             current_speed.x = speed * run_coef * AFTMathUtils.cos(angle);
  71.             current_speed.y = speed * run_coef * AFTMathUtils.sin(angle);
  72.  
  73.             model.getCurrentAnimation().setFps((float) (current_speed.length() * 5));
  74.             moveObject(current_speed);
  75.         }
  76.     };
  77.  
  78.     task_run.setNextUpdate(0.01f);
  79.     task_run.addCondition(cond_run);
  80.     task_run.addInterrupt(cond_run.invert());
  81.  
  82.     addTask(task_idle);
  83.     addTask(task_walk);
  84.     addTask(task_run);
  85. }

как вы заметили, это не слишком простой для понимания вариант, но тут скорее нужно хорошо себе представлять логику того или иного персонажа, чтобы правильно ее перенести в код. В класс AFTCondition специально добавлен метод invert(), который позволяет получить экземпляр условия обратный изначальному, чтобы не прописывать все вручную

Изменено DominaN (21.02 / 17:21) (всего 1 раз)
- 21.02.2015 / 17:26
DominaN
  Пользователь

DominaN 
Сейчас: Offline
выбор подходящей задачи осуществляется автоматически на уровне движка, программисту игры достаточно правильно настроить условия и задачи
- 2.03.2015 / 00:58
DominaN
  Пользователь

DominaN 
Сейчас: Offline
Залил последнюю версию на GitHub https://github.com/DarkPartizaN/after-engine-pc Помню, там кто-то очень просил, посмотрим, что вы можете сказать)

Изменено DominaN (2.03 / 01:12) (всего 1 раз)
- 3.03.2015 / 22:31
DominaN
  Пользователь

DominaN 
Сейчас: Offline
Добавил кой-какое освещение через framebuffer. Буду долбаться с тенями, чувствую
http://pix.academ.org/img/2015...c48cd03071921bd0.png
http://pix.academ.org/img/2015...0bbf8b17531b35cf.png
- 3.03.2015 / 23:14
Korvin
  Пользователь

Korvin 
Сейчас: Offline
DominaN, Ух ты смотрится отлично . Через framebuffer это как , опиши в двух словах ?
- 4.03.2015 / 04:32
eNvisible
  Пользователь

eNvisible 
Сейчас: Offline
Выглядит круто)
Наверх  Всего сообщений: 617
Фильтровать сообщения
Поиск по теме
Файлы топика (24)