Запилил моушены. Это заданный последовательный набор движений объекта на сцене. Впринципе не только объекта сцены, в моушен положить можно что угодно.
В сцене хранится MotionDispatcher, в нем можно создавать нити MotionThread, путем ручного создания или загрузки из xml файла. Все нити работают асинхронно. В каждой нити хранится список действий Motion, которые воспроизводятся поочереди, одно действие может хранить несколько в себе. К нити можно присвоить объект MotionObject, тогда он будет передаваться в контексте Motion.
Пример:
Я хочу что-бы волк шел потом шел и поворачивал, затем бил лапами и шел дальше, и так бесконечно. Как это сделать.
По дефолту у нас нет реализации моушенов, их надо запилить. (в дальнейшем подумаю над стандартными)
class MotionMove : public ceMotion, public ceMotionConstructor{
public:
// при загрузки из файла движок будет сам создавать нужный моушен
std::shared_ptr<ceMotion> createMotion(){
return std::shared_ptr<MotionMove>(new MotionMove);
}
// перезагрузка класса в этом методе
void setParams(const std::string ¶ms){
m_moveDistance = atof(params.c_str());
}
// само действие
bool doMotion(const std::shared_ptr<ceMotionContext> &motionContext, double frameTime){
// из контекста получаем объект и двигаем
std::static_pointer_cast<ceModel>(motionContext->motionObject())->moveForward(frameTime);
m_moveDistance -= frameTime;
return m_moveDistance > 0;
}
private:
float m_moveDistance;
};
И в том же духе остальные действия, которые будут в игре.
Все классы нужно зарегистрировать под каким-то именем я буду называть это имя класса в xml файле
engine->scene()->motionDispatcher()->registerMotionConstructor("MotionMove", std::shared_ptr<MotionMove>(new MotionMove));
// register any classes
Все, с регистрацией классов покончено, впринципе можно создать личную библиотеку моушенов и юзать в любом своем приложении.
Теперь как загрузить нить.
Пример xml файла
<cet>
<motion class="MotionChangeAnimation" params="1;10;1;10" />
<motion class="MotionMove" params="9" />
<motion together="1">
<motion class="MotionMove" params="3" />
<motion class="MotionRotate" params="-160;3" />
</motion>
<motion class="MotionChangeAnimation" params="11;20;0;10" />
<motion class="MotionWaitFinishModelAnimation" params="" />
<motion class="MotionRestart" params="" />
</cet>
Видно, что мы создаем моушен, имя класса это то имя с которым мы зарегистрировали, строка параметров будет передаваться при перезагрузке класса, а именно в setParams, там мы его ручками парсим
Если наш моешен должен выполнять одновременно несколько действий, например ходьба и поворот, то нам в моушен нужно вложить несколько моушенов, причем атрибут together отвечает за то, как будут выполняться моушены, по очереди или сразу все.
Теперь как загрузить этот файл в коде программы:
m_motionThread = m_wolf->parentScene()->motionDispatcher()->loadMotionThread("wolf_motion.cet");
m_motionThread->setMotionObject(m_wolf);
m_motionThread->setListener(this);
Тут загружается сама нить, после того как она загружена моушены начнут сразу работать. Важно задать объект для контекста так как мы хотим его в дальнейшем использовать, и последнее нить умеет возвращать callback'и.
Ну как-то так