20.02.2015 / 14:51 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   | пока что концепция такова - у нас каждый фрейм для всех 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    Пользователь  
   Сейчас: Offline 
 Имя: Денис Регистрация: 30.07.2012
   | Такой вопрос: погода есть ? если да, то как ее увидеть(включить).
   | 
  20.02.2015 / 14:58 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   | Dinisimys, пока нету, ну то есть как, в коде она есть, а включить нельзя. Я буду ее переделывать - день и ночь переводить на динамическое освещение, по-любому, а с дождем и снегом я прям хз, вид-то теперь сверху
   | 
  20.02.2015 / 15:30 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   | В принципе, прототип системы AI работает, но скажите, удобно-ли вам было бы программировать его примерно в таком виде: public void initAI() {  
    //Tasks  
    task_idle = new AFTTask() {  
   
        public void init() {  
            current_speed.reset();  
            model.setAnimation(anim_stay, 2);  
        }  
   
        public void update() {  
            angle = AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX());  
            rotateObject(angle);  
        }  
   
        public boolean done() {  
            return true;  
        }  
    };  
   
    task_idle.setNextUpdate(0.01f);  
    task_idle.addCondition(new AFTCondition() {  
   
        public boolean satisfied() {  
            return !AFTRuntime.keyPressed(AFTControllable.KEY_ANY);  
        }  
    });  
    task_idle.addInterrupt(new AFTCondition() {  
   
        public boolean satisfied() {  
            return AFTRuntime.keyPressed(AFTControllable.KEY_ANY);  
        }  
    });  
   
    setTask(task_idle);  
}  
 ?  | 
  21.02.2015 / 17:20 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   | В общем на данный момент полностью переписанный AI игрока выглядит так: public void initAI() {  
    //Conditions  
    AFTCondition cond_walk = new AFTCondition() {  
        public boolean satisfied() {  
            return AFTRuntime.keyPressed(AFTControllable.MOVE_FORWARD);  
        }  
    };  
    AFTCondition cond_run = new AFTCondition() {  
        public boolean satisfied() {  
            return (AFTRuntime.keyPressed(AFTControllable.MOVE_FORWARD) && AFTRuntime.keyPressed(AFTControllable.SPRINT));  
        }  
    };  
    //Tasks  
    //Idle  
    task_idle = new AFTTask() {  
   
        public void init() {  
            current_speed.reset();  
            model.setAnimation(anim_stay, 2);  
        }  
   
        public void update() {  
            rotateObject(AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX()));  
        }  
    };  
   
    task_idle.setNextUpdate(0.01f);  
    task_idle.addCondition(new AFTCondition() {  
   
        public boolean satisfied() {  
            return !AFTRuntime.keyPressed(AFTControllable.KEY_ANY);  
        }  
    });  
    task_idle.addInterrupt(cond_walk);  
    task_idle.addInterrupt(cond_run);  
   
    //Walk  
    task_walk = new AFTTask() {  
   
        public void init() {  
            model.setAnimation(anim_walk);  
        }  
   
        public void update() {  
            rotateObject(AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX()));  
   
            current_speed.x = speed * AFTMathUtils.cos(angle);  
            current_speed.y = speed * AFTMathUtils.sin(angle);  
   
            model.getCurrentAnimation().setFps((float) (current_speed.length() * 5));  
            moveObject(current_speed);  
        }  
    };  
   
    task_walk.setNextUpdate(0.01f);  
    task_walk.addCondition(cond_walk);  
    task_walk.addInterrupt(cond_walk.invert());  
    task_walk.addInterrupt(cond_run);  
   
    //Run  
    task_run = new AFTTask() {  
   
        public void init() {  
            model.setAnimation(anim_walk);  
        }  
   
        public void update() {  
            rotateObject(AFTMathUtils.angle(AFTRuntime.mouse_world.y - getWorldY(), AFTRuntime.mouse_world.x - getWorldX()));  
   
            current_speed.x = speed * run_coef * AFTMathUtils.cos(angle);  
            current_speed.y = speed * run_coef * AFTMathUtils.sin(angle);  
   
            model.getCurrentAnimation().setFps((float) (current_speed.length() * 5));  
            moveObject(current_speed);  
        }  
    };  
   
    task_run.setNextUpdate(0.01f);  
    task_run.addCondition(cond_run);  
    task_run.addInterrupt(cond_run.invert());  
   
    addTask(task_idle);  
    addTask(task_walk);  
    addTask(task_run);  
}  
 как вы заметили, это не слишком простой для понимания вариант, но тут скорее нужно хорошо себе представлять логику того или иного персонажа, чтобы правильно ее перенести в код. В класс AFTCondition специально добавлен метод invert(), который позволяет получить экземпляр условия обратный изначальному, чтобы не прописывать все вручную  Изменено DominaN (21.02 / 17:21) (всего 1 раз) | 
  21.02.2015 / 17:26 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   | выбор подходящей задачи осуществляется автоматически на уровне движка, программисту игры достаточно правильно настроить условия и задачи
   | 
  2.03.2015 / 00:58 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   | Залил последнюю версию на GitHub  https://github.com/DarkPartizaN/after-engine-pc Помню, там кто-то очень просил, посмотрим, что вы можете сказать)  Изменено DominaN (2.03 / 01:12) (всего 1 раз) | 
  3.03.2015 / 22:31 |  | 
DominaN    Пользователь  
   Сейчас: Offline 
 Имя: Кирилл Откуда: Смоленск Регистрация: 28.09.2011
   |  | 
  3.03.2015 / 23:14 |  | 
Korvin    Пользователь  
   Сейчас: Offline 
 Имя: Макс Откуда: Белгород Регистрация: 06.04.2011
   | DominaN, Ух ты смотрится отлично . Через  framebuffer это как , опиши в двух словах ?
   | 
  4.03.2015 / 04:32 |  | 
eNvisible    Пользователь  
   Сейчас: Offline 
 Имя: **** Откуда: В России. Регистрация: 19.07.2014
   | Выглядит круто)
   |