zoukankan      html  css  js  c++  java
  • 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 }

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

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

  • 相关阅读:
    iOS.TextKit.02.文字图片混合排版
    翻翻乐游戏源码
    Dribbble客户端应用源码
    安卓版谍报馆客户端应用源码
    多文件上传 iOS功能
    最新模仿ios版微信应用源码
    类似QQ的应用毗邻(Pilin)即时聊天源码
    很类似新版天天动听音乐播放器安卓应用源码
    高仿安卓跑酷游戏源码
    类似美丽说应用源码带有详细开发说明文档
  • 原文地址:https://www.cnblogs.com/jjxxjnzy/p/3673121.html
Copyright © 2011-2022 走看看