cocos2d-x 帧动画学习

今天学了一下cocos2d-x的帧动画,在这里记录一下,如果有什么错误的地方还请大家指出,我及时改正。在这里我创建了一个SpriterLayer的类,他是继承自CClayer的,在这里我先把头文件的定义贴出来:

 1 #ifndef SPRITER_LAYER_H
 2 #define SPRITER_LAYER_H
 3 
 4 #include "cocos2d.h"
 5 
 6 USING_NS_CC;
 7 
 8 class SpriterLayer : public CCLayer
 9 {
10 public:
11     virtual ~SpriterLayer();
12     virtual bool init();
13     CREATE_FUNC(SpriterLayer);
14     
15     static CCScene *createScene();
16 
17     CCSize size;
18 
19     void initSpriteOne();
20     void initSpriteTwo();
21     void initSpriteThree();
22     void initSpriteFourth();
23 
24     void animationEnd();
25 
26     void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
27     void update(float delta);
28 
29     CCPoint location;
30 };
31 
32 #endif

在这里我们提供了一个静态函数用来创建一个场景,然后定义了四个精灵帧动画,顺便也学习一下android的动画,之后还定义了一个动画结束之后的回调函数,接着我们重新实现了它的ccTouchesBegan函数以此来接收触摸事件,接着我们实现了update函数用来更新精灵的位置,从而实现行走动作,最后定义了一个CCPoint的对象,用来实现触目位置的记录。

接着我把其实现文件贴出来,代码如下:

  1 #include "SpriterLayer.h"
  2 
  3 SpriterLayer::~SpriterLayer()
  4 {
  5 
  6 }
  7 
  8 bool SpriterLayer::init()
  9 {
 10     if(!CCLayer::init())
 11         return false;
 12 
 13     location.x = 30;
 14     location.y = 100;
 15     size = CCDirector::sharedDirector()->getWinSize();
 16 
 17     CCLayerColor *colorLayer = CCLayerColor::create(ccc4(150, 150, 150, 230),size.width,size.height);
 18     addChild(colorLayer);
 19 
 20     CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("role.plist");
 21     
 22     initSpriteOne();
 23 
 24     initSpriteTwo();
 25 
 26     initSpriteThree();
 27 
 28     initSpriteFourth();
 29 
 30 
 31     setTouchEnabled(true);
 32 
 33     scheduleUpdate();
 34     
 35 
 36     return  true;
 37 }
 38 
 39 CCScene *SpriterLayer::createScene()
 40 {
 41     CCScene *scene = NULL;
 42 
 43     scene = CCScene::create();
 44 
 45     SpriterLayer *layer= SpriterLayer::create();
 46 
 47     scene->addChild(layer);
 48 
 49 
 50     return scene;
 51 }
 52 
 53 void SpriterLayer::initSpriteOne()
 54 {
 55     CCSprite  *sprite = CCSprite::createWithSpriteFrameName("Img_ZRun1.png");
 56     addChild(sprite);
 57     sprite->setPosition(ccp(100,size.height/2));
 58 
 59     CCArray *frameArray = CCArray::create();
 60     frameArray->retain();
 61 
 62     for (int i=1;i<7;i++)
 63     {
 64         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_ZRun%d.png",i)->getCString());
 65         frameArray->addObject(frame);
 66     }
 67     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
 68 
 69     CCAnimate *animate = CCAnimate::create(animation);
 70     CCAction *action = CCRepeatForever::create(animate);
 71 
 72     sprite->runAction(action);
 73 }
 74 
 75 void SpriterLayer::initSpriteTwo()
 76 {
 77     CCSprite *sprite = CCSprite::createWithSpriteFrameName("Img_Zhici1.png");
 78     addChild(sprite);
 79     sprite->setPosition(ccp(300,size.height/2));
 80 
 81     CCArray *frameArray = CCArray::create();
 82     frameArray->retain();
 83 
 84     for (int i=1;i<9;i++)
 85     {
 86         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_Zhici%d.png",i)->getCString());
 87         frameArray->addObject(frame);
 88     }
 89 
 90     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
 91     CCAnimate *animate = CCAnimate::create(animation);
 92 
 93     //CCAction *action = CCSequence::create(CCSpawn::create(animate,CCMoveTo::create(2.0f,ccp(700,100)),NULL),NULL);
 94 
 95     CCAction *action = CCSequence::create(animate,CCCallFunc::create(this,callfunc_selector(SpriterLayer::animationEnd)),NULL);
 96 
 97     sprite->runAction(action);
 98 
 99 }
100 
101 void SpriterLayer::initSpriteThree()
102 {
103     CCSprite *sprite = CCSprite::createWithSpriteFrameName("Img_Zhn1.png");
104     addChild(sprite);
105     sprite->setPosition(ccp(500,size.height/2));
106 
107     CCArray *frameArray = CCArray::create();
108     frameArray->retain();
109 
110     for (int i=1;i<17;i++)
111     {
112         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_Zhn%d.png",i)->getCString());
113         frameArray->addObject(frame);
114     }
115 
116     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
117     CCAnimate *animate = CCAnimate::create(animation);
118 
119     CCAction *action = CCRepeatForever::create(animate);
120 
121     sprite->runAction(action);
122 
123 }
124 
125 
126 void SpriterLayer::initSpriteFourth()
127 {
128     CCSprite *sprite = CCSprite::createWithSpriteFrameName("Img_Zwlak1.png");
129     addChild(sprite,0,1);
130 
131     sprite->setPosition(ccp(30,100));
132 
133     CCArray *frameArray = CCArray::create();
134     frameArray->retain();
135 
136     for (int i=1;i<7;i++)
137     {
138         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_Zwlak%d.png",i)->getCString());
139         frameArray->addObject(frame);
140     }
141 
142     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
143     animation->setRestoreOriginalFrame(true);  //动画完成之后还原为第一帧
144     CCAnimate *animate = CCAnimate::create(animation);
145 
146     CCAction *action = CCRepeatForever::create(animate);
147     
148     sprite->runAction(action);
149 }
150 
151 void SpriterLayer::animationEnd()
152 {
153     CCLog("animation finish");
154 }
155 
156 void SpriterLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
157 {    
158     CCTouch *touch = (CCTouch *)( pTouches->anyObject());
159 
160 #ifdef DEBUG
161     CCPoint point = touch->getLocation();
162     CCLog("location x=%2.2f	 y=%2.2f
",point.x,point.y);
163 
164     CCPoint viewPoint = touch->getLocationInView();
165     CCLog("viewLocation x=%2.2f	 y=%2.2f
",viewPoint.x,viewPoint.y);
166 #endif
167 
168     location = touch->getLocationInView();
169 
170 }
171 
172 void SpriterLayer::update(float delta)
173 {
174     CCSprite *sprite = (CCSprite *)this->getChildByTag(1);
175 
176     if (sprite!=NULL)
177     {
178         if(sprite->getPositionX()>location.x)
179         {
180             sprite->setScaleX(-1);
181         }
182         else
183         {
184             sprite->setScaleX(1);
185         }
186 
187         sprite->setPosition(ccp(location.x,100));
188     }
189 }

接下来从init函数一步一步往下看:

实现我们调用了父对象的init方法,接着我们在添加了一个CCLayerColor层,这个主要是一个背景色,不然背景是黑色的不太好看。接着我们调用

1 CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("role.plist");

这行代码是把我们所需要的资源添加到缓冲池里,这个plist文件是用TexturPackerGUI生成的,具体的大家google一下吧。

接着我们初始化调用initSpriteOne函数初始化我们的第一个精灵,代码如下:

 1 void SpriterLayer::initSpriteOne()
 2 {
 3     CCSprite  *sprite = CCSprite::createWithSpriteFrameName("Img_ZRun1.png");
 4     addChild(sprite);
 5     sprite->setPosition(ccp(100,size.height/2));
 6 
 7     CCArray *frameArray = CCArray::create();
 8     frameArray->retain();
 9 
10     for (int i=1;i<7;i++)
11     {
12         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_ZRun%d.png",i)->getCString());
13         frameArray->addObject(frame);
14     }
15     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
16 
17     CCAnimate *animate = CCAnimate::create(animation);
18     CCAction *action = CCRepeatForever::create(animate);
19 
20     sprite->runAction(action);
21 }

我们首先创建出一个精灵对象,这个地方的图像资源是从我们刚刚加入的缓冲池里取出的。接着我们创建了一个CCArray的数组用来存放我们的frame对象。接着我们通过一个循环把fram对象从缓冲池取出来加入到我们刚刚创建的数组,取出我们所需的frame之后我们就可以开始创建我们的动画了:

1 CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);

根据我们取出的序列帧创建一个动画,动画的间隔时间设置为0.1f,接着我们创建CCAnimate对象,创建完成之后调用下面的代码创建action

1 CCAction *action = CCRepeatForever::create(animate);

在这里我们创建了一个重复动画,看这个方法的名字我们就知道这个动画是一只在循环的,接着我们就可以为精灵执行我们的动画了

1 sprite->runAction(action);

不知道在window下怎么生成gif,效果大家自己编译出来看吧 

接着我们看看第二个精灵动画,代码如下:

 1 void SpriterLayer::initSpriteTwo()
 2 {
 3     CCSprite *sprite = CCSprite::createWithSpriteFrameName("Img_Zhici1.png");
 4     addChild(sprite);
 5     sprite->setPosition(ccp(300,size.height/2));
 6 
 7     CCArray *frameArray = CCArray::create();
 8     frameArray->retain();
 9 
10     for (int i=1;i<9;i++)
11     {
12         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_Zhici%d.png",i)->getCString());
13         frameArray->addObject(frame);
14     }
15 
16     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
17     CCAnimate *animate = CCAnimate::create(animation);
18 
19     CCAction *action = CCSequence::create(animate,CCCallFunc::create(this,callfunc_selector(SpriterLayer::animationEnd)),NULL);
20 
21     sprite->runAction(action);
22 
23 }

这个精灵的大部分代码和第一个精灵的是相同的,唯一不同的是这个帧动画只会执行一次,执行完成动画之后会调用animationEnd函数。

第三个精灵和第一个是一样的就不看了,我们看看碟四个精灵,看看我们如何实现行走:

 1 void SpriterLayer::initSpriteFourth()
 2 {
 3     CCSprite *sprite = CCSprite::createWithSpriteFrameName("Img_Zwlak1.png");
 4     addChild(sprite,0,1);
 5 
 6     sprite->setPosition(ccp(30,100));
 7 
 8     CCArray *frameArray = CCArray::create();
 9     frameArray->retain();
10 
11     for (int i=1;i<7;i++)
12     {
13         CCSpriteFrame *frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(CCString::createWithFormat("Img_Zwlak%d.png",i)->getCString());
14         frameArray->addObject(frame);
15     }
16 
17     CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.1f);
18     animation->setRestoreOriginalFrame(true);  //动画完成之后还原为第一帧
19     CCAnimate *animate = CCAnimate::create(animation);
20 
21     CCAction *action = CCRepeatForever::create(animate);
22     
23     sprite->runAction(action);
24 }

这个动画其实和第一个是一样的,我们要重写CCLayer的ccTouchesBegan函数获取当前触摸的坐标,接着我们看看ccTouchesBegan函数的实现:

 1 void SpriterLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
 2 {    
 3     CCTouch *touch = (CCTouch *)( pTouches->anyObject());
 4 
 5 #ifdef DEBUG
 6     CCPoint point = touch->getLocation();
 7     CCLog("location x=%2.2f	 y=%2.2f
",point.x,point.y);
 8 
 9     CCPoint viewPoint = touch->getLocationInView();
10     CCLog("viewLocation x=%2.2f	 y=%2.2f
",viewPoint.x,viewPoint.y);
11 #endif
12 
13     location = touch->getLocationInView();
14 
15 }

在这里我们看到有个debug信息,我们看到有两个函数:getLocation和getLocationInView,这两个函数是用来转换我们所取坐标的,一个取得的是opengl的坐标,另外一个则是cocos2d的坐标,在这里我们要使用的是cocos2d的坐标,所以把该坐标值赋值给location。

接着我们在update函数中实现对第四个精灵对象的移动,updae函数如下:

 1 void SpriterLayer::update(float delta)
 2 {
 3     CCSprite *sprite = (CCSprite *)this->getChildByTag(1);
 4 
 5     if (sprite!=NULL)
 6     {
 7         if(sprite->getPositionX()>location.x)
 8         {
 9             sprite->setScaleX(-1);
10         }
11         else
12         {
13             sprite->setScaleX(1);
14         }
15 
16         sprite->setPosition(ccp(location.x,100));
17     }
18 }

这样我们就实现了对精灵位置的移动,看上去就是行走状态了。

声明:该代码所使用的图片来源于网络

原文地址:https://www.cnblogs.com/jjxxjnzy/p/3673121.html