具体需求:飞机向左移动播放向左移动动画,向右移动播放向右移动的动画
实现思路:cocos2d-x里面提供了Animation类,该类继承Ref和Clonable,并不继承Action基类,所以无法直接传入Node::runAction()方法中,但Animate类却继承了Action类,且可以用Animation类来进行构造。
所以具体实现方法是:用Animation类加载动画,Animate类使用已经加载好的Animation来创建对象,飞机再对Animation类进行runAction();
具体代码如下:
头文件:
#ifndef __PLAYER__H
#define __PLAYER_H__
#include "cocos2d.h"
USING_NS_CC;
enum
{
E_FLY_NONE,
E_FLY_STRAIGHT,
E_FLY_LEFT,
E_FLY_RIGHT
};
class CPlayer:public Sprite
{
public:
CPlayer();
~CPlayer();
static CPlayer* create();
virtual bool init();
void createAnimate();
void changeFlyAnimate(int nFlyState);
bool onTouchBegan(Touch* pTouch, Event* pEvent);
void onTouchMoved(Touch* pTouch, Event* pEvent);
void onTouchEnded(Touch* pTouch, Event* pEvent);
//CREATE_FUNC(CPlayer);
private:
bool m_bMove;
Animate* m_pAnimateS;
Animate* m_pAnimateL;
int m_nFlyState;
};
#endif
具体实现:
1、加载Animation,用其加载图片,并使用它对Animate进行创建:
//直行动画
Animation* pAnimation = Animation::create();
char szName[32];
for (int i = 0; i < 2; i++)
{
sprintf_s(szName, "Plane0_%d.png", i);
pAnimation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(szName));
}
pAnimation->setDelayPerUnit(0.2f);
m_pAnimateS = Animate::create(pAnimation);
m_pAnimateS->retain();
/*runAction(RepeatForever::create(m_pAnimateS));*/
//左行动画
Animation* pAnimationL = Animation::create();
for (int i = 2; i < 4; i++)
{
sprintf_s(szName, "Plane0_%d.png", i);
pAnimationL->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(szName));
}
pAnimationL->setDelayPerUnit(0.2f);
m_pAnimateL = Animate::create(pAnimationL);
m_pAnimateL->retain();
这里的两个Animate都设置成飞机的成员变量。
我们的加载图片的过程是:
创建空的Animatetion: 调用Animatetion::create(void)方法,
加载图片:调用Animatetion::addSpriteFrame(SpriteFrame)方法,其中SpriteFrame(精灵帧)通过已经加载好的精灵帧缓存区中通过SpriteFrameCache::getSpriteFrameByName(const string &name)方法获取
用已经加载好的Animation创建Animate:调用Animation::create(Animate)方法。
其中setDelayPerUnit方法是设置动画播放的间隔时间。
因为Animate并不是创建一开始就会被runAction(满足一定条件才会播放动画效果)所以要将它们retain()防止被自动释放池释放内存。因此我们要对其主动释放内存(我们这里在析构函数中对其release)。
2、根据不同情况对Animate类进行runAction:
采用状态机管理模式,代码如下:
void CPlayer::onTouchMoved(Touch* pTouch, Event* pEvent)
{
if (m_bMove)
{
if (pTouch->getLocation().x<this->getPositionX())
{
changeFlyAnimate(E_FLY_LEFT);
}
else if (pTouch->getLocation().x>this->getPositionX())
{
changeFlyAnimate(E_FLY_RIGHT);
}
this->setPosition(pTouch->getLocation());
}
CCLOG("move");
}
void CPlayer::onTouchEnded(Touch* pTouch, Event* pEvent)
{
changeFlyAnimate(E_FLY_STRAIGHT);
m_bMove = false;
CCLOG("end");
}
void CPlayer::changeFlyAnimate(int nFlyState)
{
if (nFlyState==m_nFlyState)
{
return;
}
stopAllActions();
m_nFlyState = nFlyState;
switch (m_nFlyState)
{
case E_FLY_STRAIGHT:
this->runAction(RepeatForever::create(m_pAnimateS));
break;
case E_FLY_LEFT:
setFlippedX(false);
this->runAction(RepeatForever::create(m_pAnimateL));
break;
case E_FLY_RIGHT:
setFlippedX(true);
this->runAction(RepeatForever::create(m_pAnimateL));
break;
default:
break;
}
}
------------------------------------------------------------------------待完善--------------------------------------------------------------------------------