cocos2dx style AnimationState event callback for CCSkeletonAnimation.

This commit is contained in:
NathanSweet 2013-09-26 21:44:22 +02:00
parent 067a84339b
commit 9443ecb09c
5 changed files with 59 additions and 6 deletions

View File

@ -67,6 +67,7 @@ struct AnimationState {
TrackEntry** tracks;
AnimationStateListener listener;
void* context;
};
/* @param data May be 0 for no mixing. */

View File

@ -17,11 +17,12 @@ CCScene* ExampleLayer::scene () {
bool ExampleLayer::init () {
if (!CCLayer::init()) return false;
skeletonNode = CCSkeletonAnimation::createWithFile("spineboy.json", "spineboy.atlas");
skeletonNode->setMix("walk", "jump", 0.2f);
skeletonNode->setMix("jump", "walk", 0.4f);
skeletonNode->setListener(this, animationStateEvent_selector(ExampleLayer::animationStateEvent));
skeletonNode->setAnimation(0, "walk", true);
// This shows how to setup animations to play back to back.
//skeletonNode->addAnimation(0, "jump", false);
@ -53,4 +54,25 @@ void ExampleLayer::update (float deltaTime) {
if (entry->time > 1) skeletonNode->setAnimation(0, "walk", true);
}
// if (entry->time > 0.1) CCDirector::sharedDirector()->replaceScene(ExampleLayer::scene());
}
}
void ExampleLayer::animationStateEvent (CCSkeletonAnimation* node, int trackIndex, EventType type, Event* event, int loopCount) {
TrackEntry* entry = AnimationState_getCurrent(node->state, trackIndex);
const char* animationName = (entry && entry->animation) ? entry->animation->name : 0;
switch (type) {
case ANIMATION_START:
CCLog("%d start: %s", trackIndex, animationName);
break;
case ANIMATION_END:
CCLog("%d end: %s", trackIndex, animationName);
break;
case ANIMATION_COMPLETE:
CCLog("%d complete: %s, %d", trackIndex, animationName, loopCount);
break;
case ANIMATION_EVENT:
CCLog("%d event: %s, %s: %d, %f, %s", trackIndex, animationName, event->data->name, event->intValue, event->floatValue, event->stringValue);
break;
}
fflush(stdout);
}

View File

@ -7,9 +7,6 @@
#include <spine/spine-cocos2dx.h>
class ExampleLayer: public cocos2d::CCLayer {
private:
spine::CCSkeletonAnimation* skeletonNode;
public:
static cocos2d::CCScene* scene ();
@ -17,6 +14,10 @@ public:
virtual void update (float deltaTime);
CREATE_FUNC (ExampleLayer);
private:
spine::CCSkeletonAnimation* skeletonNode;
void animationStateEvent (spine::CCSkeletonAnimation* node, int trackIndex, EventType type, Event* event, int loopCount);
};
#endif // _EXAMPLELAYER_H_

View File

@ -42,6 +42,14 @@ using std::vector;
namespace spine {
extern "C" static void callback (AnimationState* state, int trackIndex, EventType type, Event* event, int loopCount) {
((CCSkeletonAnimation*)state->context)->onAnimationStateEvent(trackIndex, type, event, loopCount);
}
void CCSkeletonAnimation::onAnimationStateEvent (int trackIndex, EventType type, Event* event, int loopCount) {
if (listenerInstance) (listenerInstance->*listenerMethod)(this, trackIndex, type, event, loopCount);
}
CCSkeletonAnimation* CCSkeletonAnimation::createWithData (SkeletonData* skeletonData) {
CCSkeletonAnimation* node = new CCSkeletonAnimation(skeletonData);
node->autorelease();
@ -61,7 +69,12 @@ CCSkeletonAnimation* CCSkeletonAnimation::createWithFile (const char* skeletonDa
}
void CCSkeletonAnimation::initialize () {
listenerInstance = 0;
listenerMethod = 0;
state = AnimationState_create(AnimationStateData_create(skeleton->data));
state->context = this;
state->listener = callback;
}
CCSkeletonAnimation::CCSkeletonAnimation (SkeletonData *skeletonData)
@ -101,12 +114,19 @@ void CCSkeletonAnimation::setAnimationStateData (AnimationStateData* stateData)
ownsAnimationStateData = true;
state = AnimationState_create(stateData);
state->context = this;
state->listener = callback;
}
void CCSkeletonAnimation::setMix (const char* fromAnimation, const char* toAnimation, float duration) {
AnimationStateData_setMixByName(state->data, fromAnimation, toAnimation, duration);
}
void CCSkeletonAnimation::setListener (CCObject* instance, SEL_AnimationStateEvent method) {
listenerInstance = instance;
listenerMethod = method;
}
TrackEntry* CCSkeletonAnimation::setAnimation (int trackIndex, const char* name, bool loop) {
return AnimationState_setAnimationByName(state, trackIndex, name, loop);
}

View File

@ -40,6 +40,10 @@
namespace spine {
class CCSkeletonAnimation;
typedef void (cocos2d::CCObject::*SEL_AnimationStateEvent)(spine::CCSkeletonAnimation* node, int trackIndex, EventType type, Event* event, int loopCount);
#define animationStateEvent_selector(_SELECTOR) (SEL_AnimationStateEvent)(&_SELECTOR)
/** Draws an animated skeleton, providing an AnimationState for applying one or more animations and queuing animations to be
* played later. */
class CCSkeletonAnimation: public CCSkeleton {
@ -61,17 +65,22 @@ public:
void setAnimationStateData (AnimationStateData* stateData);
void setMix (const char* fromAnimation, const char* toAnimation, float duration);
void setListener (CCObject* instance, SEL_AnimationStateEvent method);
TrackEntry* setAnimation (int trackIndex, const char* name, bool loop);
TrackEntry* addAnimation (int trackIndex, const char* name, bool loop, float delay = 0);
TrackEntry* getCurrent (int trackIndex = 0);
void clearAnimation ();
void clearAnimation (int trackIndex = 0);
void onAnimationStateEvent (int trackIndex, EventType type, Event* event, int loopCount);
protected:
CCSkeletonAnimation ();
private:
typedef CCSkeleton super;
CCObject* listenerInstance;
SEL_AnimationStateEvent listenerMethod;
bool ownsAnimationStateData;
void initialize ();