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
| Выглядит круто)
|