#include <irrlicht.h>
#include <iostream>
#include <vector>
using namespace irr;
enum ANIMATION_STATE
{
EAS_IDLE,
EAS_RUNNING,
EAS_JUMPING,
EAS_ATTACKING,
EAS_COUNT
};
class AnimationBinder
{
public:
virtual void bind() = 0;
virtual void unbind() = 0;
virtual int priority() = 0;
virtual bool operator < (AnimationBinder *other)
{
return priority() < other->priority();
}
bool activated;
bool binded;
};
class GenericState : public AnimationBinder
{
public:
GenericState(scene::IAnimatedMeshSceneNode* NePlayer,int AnimPriority, int FrameStart, int FrameEnd, bool Frameloop)
{
binded = false;
activated = false;
NodePlayer = NePlayer;
Apriority = AnimPriority;
start = FrameStart;
end = FrameEnd;
loop = Frameloop;
}
virtual void bind()
{
std::cout << "bind::" << priority() << std::endl;
binded = true;
NodePlayer->setAnimationSpeed(10);
NodePlayer->setLoopMode(loop);
NodePlayer->setFrameLoop(start,end);
}
virtual void unbind()
{
binded = false;
std::cout << "unbind::" << priority() << std::endl;
}
virtual int priority()
{
return Apriority;
}
scene::IAnimatedMeshSceneNode* NodePlayer;
int Apriority;
int start;
int end;
bool loop;
};
class AnimationManager
{
public:
AnimationManager(scene::IAnimatedMeshSceneNode* NePlayer)
{
binded = 0;
anim.push_back(new GenericState(NePlayer,0,206,250,true)); // idle
anim.push_back(new GenericState(NePlayer,1, 0, 13,true)); // running
anim.push_back(new GenericState(NePlayer,3, 94,102,true)); // jumping
anim.push_back(new GenericState(NePlayer,5, 32, 44,true)); // attacking
activate(EAS_IDLE, true);
}
void activate(int animNumber, bool value)
{
AnimationBinder *current = anim[animNumber];
current->activated = value;
// idle at default
current = anim[0];
for(int i = 0; i<anim.size(); ++i)
if(current < anim[i] && anim[i]->activated)
current = anim[i];
if(!current->binded && current != binded)
{
if(binded)
binded->unbind();
current->bind();
binded = current;
}
}
private:
std::vector<AnimationBinder*> anim;
AnimationBinder *binded;
};
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::IAnimatedMeshSceneNode* NePlayer)
{
anim = new AnimationManager(NePlayer);
}
virtual bool OnEvent(const SEvent& event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT )
{
if(event.KeyInput.Key == irr::KEY_SPACE)
anim->activate(EAS_JUMPING, event.KeyInput.PressedDown);
if(event.KeyInput.Key == irr::KEY_KEY_Z)
anim->activate(EAS_RUNNING, event.KeyInput.PressedDown);
if(event.KeyInput.Key == irr::KEY_RETURN)
anim->activate(EAS_ATTACKING, event.KeyInput.PressedDown);
}
return false;
}
private:
AnimationManager *anim;
};
int main()
{
IrrlichtDevice* device = createDevice(irr::video::EDT_OPENGL,
core::dimension2d<u32>(640, 480), 16, false, false, false);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
scene::IAnimatedMeshSceneNode* anms =
smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"));
anms->setMaterialFlag(video::EMF_LIGHTING, false);
anms->setScale(core::vector3df(2.f,2.f,2.f));
anms->setRotation(core::vector3df(0,-90,0));
smgr->addCameraSceneNodeFPS();
device->getCursorControl()->setVisible(false);
MyEventReceiver receiver(anms);
device->setEventReceiver(&receiver);
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,113,113,133));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}