Last active
May 13, 2016 07:55
-
-
Save stevetranby/ce0bf403810ae6ba4aa213a59b45f8ef to your computer and use it in GitHub Desktop.
Animate multiple Sprite Nodes each with a separate Animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "extensions/STActions.h" | |
USING_NS_CC; | |
//////////////////////////////////////////////////////////////////////// | |
STAnimateInSync::STAnimateInSync() {} | |
STAnimateInSync::~STAnimateInSync() { | |
// TODO: release all animtargets | |
} | |
//////////////////////////////////////////////////////////////////////// | |
STAnimateInSync* STAnimateInSync::create(Animation* pAnim, const std::vector<AnimationTargetPair>& animsTargetsToSync) | |
{ | |
STAnimateInSync *ret = new STAnimateInSync(); | |
if (ret && ret->initWithAnimation(pAnim, animsTargetsToSync)) | |
{ | |
ret->autorelease(); | |
return ret; | |
} | |
CC_SAFE_DELETE(ret); | |
return nullptr; | |
} | |
bool STAnimateInSync::initWithAnimation(Animation* pAnim, const std::vector<AnimationTargetPair>& animsTargetsToSync) | |
{ | |
if(! Animate::initWithAnimation(pAnim)) | |
return false; | |
// stash the rest of the animations and target sprites | |
for (auto animTarget : animsTargetsToSync) | |
{ | |
auto anim = animTarget.first; | |
auto target = animTarget.second; | |
anim->retain(); | |
target->retain(); | |
_animTargets.push_back(std::make_pair(anim, target)); | |
} | |
return true; | |
} | |
//////////////////////////////////////////////////////////////////////// | |
STAnimateInSync* STAnimateInSync::clone() const | |
{ | |
STAnimateInSync *pCopy = new STAnimateInSync(); | |
// TODO: just clone vector?? | |
std::vector<AnimationTargetPair> animTargetPairs; | |
for(auto& animTarget : _animTargets) { | |
animTargetPairs.push_back(animTarget); | |
} | |
pCopy->initWithAnimation(getAnimation()->clone(), animTargetPairs); | |
return pCopy; | |
} | |
// MARK: - | |
void STAnimateInSync::update(float t) | |
{ | |
Animation* _animation = getAnimation(); | |
// if t==1, ignore. Animation should finish with t==1 | |
if( t < 1.f ) { | |
t *= _animation->getLoops(); | |
// new loop? If so, reset frame counter | |
unsigned int loopNumber = (unsigned int)t; | |
if( loopNumber > _executedLoops ) { | |
_nextFrame = 0; | |
_executedLoops++; | |
} | |
// new t for animations | |
t = fmodf(t, 1.f); | |
} | |
auto numberOfFrames = _animation->getFrames().size(); | |
SpriteFrame *frameToDisplay = nullptr; | |
for(auto i = _nextFrame; i < numberOfFrames; i++ ) | |
{ | |
float splitTime = _splitTimes->at(size_t(i)); | |
if( splitTime <= t ) | |
{ | |
auto frame = _animation->getFrames().at(i); | |
frameToDisplay = frame->getSpriteFrame(); | |
(static_cast<Sprite*>(_target)->setSpriteFrame(frameToDisplay)); | |
// sync targets 2+ (iterator i through Animations, iterator j through Sprite targets) | |
for (auto animTarget : _animTargets) | |
{ | |
auto anim2 = animTarget.first; | |
auto target2 = animTarget.second; | |
if(i < anim2->getFrames().size()) { | |
auto frame2 = anim2->getFrames().at(i); | |
auto frameToDisplay2 = frame2->getSpriteFrame(); | |
target2->setSpriteFrame(frameToDisplay2); | |
} | |
} | |
_nextFrame = i+1; | |
} | |
else | |
{ | |
// Issue 1438. Could be more than one frame per tick, due to low frame rate or frame delta < 1/FPS | |
break; | |
} | |
} | |
} | |
Animate* STAnimateInSync::reverse() const | |
{ | |
CCASSERT(false, "Not implemented!"); | |
return nullptr; | |
// auto arr = getAnimation()->getFrames(); | |
// arr.reverse(); | |
// auto newAnim = Animation::create(arr, | |
// _animation->getDelayPerUnit(), | |
// _animation->getLoops()); | |
// newAnim->setRestoreOriginalFrame(_animation->getRestoreOriginalFrame()); | |
// | |
// | |
// // Sync Animation | |
// auto arrayToSync = _animationToSync->getFrames(); | |
// arrayToSync.reverse(); | |
// auto newAnimToSync = Animation::create(arrayToSync, | |
// _animationToSync->getDelayPerUnit(), | |
// _animationToSync->getLoops()); | |
// newAnimToSync->setRestoreOriginalFrame(_animation->getRestoreOriginalFrame()); | |
// | |
// // Sync Animation 2 | |
// if(_animationToSync2 && _targetToSync2) | |
// { | |
// auto arrayToSync2 = _animationToSync2->getFrames(); | |
// arrayToSync2.reverse(); | |
// auto newAnimToSync2 = Animation::create(arrayToSync2, | |
// _animationToSync2->getDelayPerUnit(), | |
// _animationToSync2->getLoops()); | |
// newAnimToSync2->setRestoreOriginalFrame(_animation->getRestoreOriginalFrame()); | |
// return create(newAnim, newAnimToSync, _targetToSync, newAnimToSync2, _targetToSync2); | |
// } | |
// else | |
// { | |
// return create(newAnim, newAnimToSync, _targetToSync, nullptr, nullptr); | |
// } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef std::pair<cocos2d::Animation*, cocos2d::Sprite*> AnimationTargetPair; | |
class STAnimateInSync : public cocos2d::Animate | |
{ | |
public: | |
STAnimateInSync(); | |
virtual ~STAnimateInSync(); | |
static STAnimateInSync* create(cocos2d::Animation* pAnim, const std::vector<AnimationTargetPair>& animsTargetsToSync); | |
bool initWithAnimation(cocos2d::Animation* pAnim, const std::vector<AnimationTargetPair>& animsTargetsToSync); | |
void update(float t) override; | |
STAnimateInSync* clone() const override; | |
cocos2d::Animate* reverse() const override; | |
private: | |
std::vector<AnimationTargetPair> _animTargets; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// container class might hold the layers | |
// Sprite* _spriteLayer1, *_spriteLayer2, *_spriteLayer3; | |
// animation to sprite map | |
std::vector<AnimationTargetPair> animTargets; | |
Animation* anim1 = // get animation from somewhere | |
animTargets.push_back(std::make_pair(anim1, _spriteLayer1)); | |
Animation* anim2 = // get animation from somewhere | |
animTargets.push_back(std::make_pair(anim2, _spriteLayer2)); | |
Animation* anim3 = // get animation from somewhere | |
animTargets.push_back(std::make_pair(anim3, _spriteLayer3)); | |
// Run action on some Node* that exists as long as sprite layers | |
//auto animAction = Animate::create(animation); | |
auto animAction = STAnimateInSync::create(animation, animTargets); | |
auto action = RepeatForever::create(animAction); | |
// run on a container node holding the layers | |
this->runAction(action); | |
// or run on base layer | |
_spriteLayer1->runAction(action); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment