cocos2d-x飞机大战——飞机移动的动画效果

具体需求:飞机向左移动播放向左移动动画,向右移动播放向右移动的动画

实现思路: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;
	}
}

------------------------------------------------------------------------待完善--------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/qq_41791653/article/details/82498931