本文实践自 Ray Wenderlich、Tony Dahbura 的文章《How to Use Animations and Sprite Sheets in Cocos2D 2.X》,原文链接http://www.raywenderlich.com/32045/how-to-use-animations-and-sprite-sheets-in-cocos2d-2-x 。在这篇文章,将会学习到怎样创建一个简单的熊行走动画,怎样使用精灵表单,怎样改变熊行走的方向等等。

教程截图:

让我们首先创建一个project骨架--使用cocos2dproject模板创建一个新的项目并取名为AnimBear.

接下来,先下载熊行走的图片

当你解压之后,看看那些图片---它们不过一张张单个的熊在行走的动画帧。可是,当你把它们连续地放映,就会看到一只熊在移动。

3.下载(点击打开链接Texture Packer工具,当前为3.1.2版本号。拖动资源图片文件到Texture
Packer的右边窗体,将会自己主动载入文件。左边窗体中的Geometry面板,调整Max size为4096x4096,由于默认尺寸不够满足大小。Layout面板,设置Trim mode为None,不须要移除透明像素。完毕之后,例如以下图所看到的:

在”Resources“文件夹下新建文件夹”HDR“。确定Output面板中Data Format选中cocos2d,Data
filename定位到”...\AnimBear\Resources\HDR“路径,文件名称为AnimBear.plist。保存之后,Texture file将会自己主动填充文件名称。然后,点击AutoSD设置button,下拉选择Presets项为”cocos2d-x
HDR/HD/SD“,点击”Apply“button,这使得在公布时可以自己主动创建和保存多种规则的精灵表单,例如以下图所看到的:

最后,点击工具栏button”Publish“,将会自己主动生成精灵表单和纹理文件,例如以下图所看到的:

能够用plist Editor Pro打开AnimBear.plist文件,能够看到它由两部分组成——帧和元数据。在帧部分,每个图像都有一个属性,用来描写叙述位于精灵表单中的包围框。例如以下图所看到的:

3.一个简单的动画。打开HelloWorldScene.h文件,加入例如以下代码:

1

2

3

4

5

6
    CC_SYNTHESIZE_RETAIN(cocos2d::CCSprite*, _bear, Bear);

    CC_SYNTHESIZE_RETAIN(cocos2d::CCAction*, _walkAction, WalkAction);

    CC_SYNTHESIZE_RETAIN(cocos2d::CCAction*, _moveAction, MoveAction);



private:

    bool _bearMoving;
 
在HelloWorldScene.h加入构造函数:
Helloworld();
 
打开HelloWorldScene.cpp文件,新建构造函数,在构造函数里面,加入例如以下代码:
1

2

3

4

5

6

7
HelloWorld::HelloWorld()

{

    _bear = NULL;

    _walkAction = NULL;

    _moveAction = NULL;

    _bearMoving = false;

}
改动init函数,为例如以下代码: 
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37
bool HelloWorld::init()

{

    bool bRet = false;

    do

    {

        CC_BREAK_IF(!CCLayer::init());

       

        //1) Cache the sprite frames and texture

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



        //2) Create a sprite batch node

        CCSpriteBatchNode *spriteSheet = CCSpriteBatchNode::create("AnimBear.png");

        this->addChild(spriteSheet);



        //3) Gather the list of frames

        CCArray *walkAnimFrames = CCArray::create();

        for (int i =1; i <=8; ++i)

        {

            walkAnimFrames->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(

                CCString::createWithFormat("bear%d.png", i)->getCString()));

        }

       

        //4) Create the animation object

        CCAnimation *walkAnim = CCAnimation::createWithSpriteFrames(walkAnimFrames,0.1f);



        //5) Create the sprite and run the animation action

        CCSize winSize = CCDirector::sharedDirector()->getWinSize();

        this->setBear(CCSprite::createWithSpriteFrameName("bear1.png"));

        this->getBear()->setPosition(ccp(winSize.width /2, winSize.height /2));

        this->setWalkAction(CCRepeatForever::create(CCAnimate::create(walkAnim)));

        this->getBear()->runAction(this->getWalkAction());

        spriteSheet->addChild(this->getBear());



        bRet = true;

    } while (0);

    return bRet;

}
以上各个步骤说明例如以下:

①.缓存精灵帧和纹理。调用CCSpriteFrameCache的addSpriteFramesWithFile方法,传入之前生成的属性列表文件名。这种方法做了例如以下事情:

  • 从属性列表文件的元数据部分,取出textureFileName的值,作为纹理文件的文件名称,在这里为AnimBear.png,加载文件到CCTextureCache纹理缓存中。注意,这里会依据设定的资源搜索路径来自己主动寻找正确的文件。
  • 解析属性列表文件,使用CCSpriteFrame对象来内部地跟踪全部精灵的信息。

②.创建一个精灵批处理节点。创建CCSpriteBatchNode对象,传入了精灵表单图像名称。精灵表单的工作方式例如以下:

  • 创建CCSpriteBatchNode对象,传入包括全部精灵的图像文件的名称,将这个对象加入到场景里面。
  • 如今,不论什么时候创建来自这个精灵表单的精灵,都应当将这个精灵加入到这个CCSpriteBatchNode对象里。仅仅要精灵是来自这个精灵表单的,那么就会正常工作,否则会报错。
  • CCSpriteBatchNode代码智能地将CCSprite孩子对象在一次的OpenGL ES调用中进行绘制,而不是多次调用,而这会使得速度快得多。

③.採集帧列表。为了创建帧列表,须要简单地遍历图片的名称(它们被命名为Bear1.png -> Bear8.png,这是一个惯例),然后,从CCSpriteFrameCache里寻找指定名称的精灵帧。请记住,这些应该已经在缓存中,由于之前调用了addSpriteFramesWithFile方法。

④.创建动画对象。通过传入精灵帧列表,创建CCAnimation对象,并指定动画的播放速度。这里使用0.1秒作为帧之间的延迟时间。

⑤.创建精灵和执行动画动作。以某一帧来创建精灵(即熊),放置在屏幕中心。传入CCAnimation对象,创建CCAnimate对象,并让熊执行这个动作。最后,将熊加入到精灵表单里。注意,假设没有加入到精灵表单里,而是加入到层里的话,就不会得到性能的优化。

为了能在不同分辨率下,载入不同的资源,须要先设置下分辨率适配,打开AppDelegate.cpp文件,在applicationDidFinishLaunching函数里面,最上面代码改动为:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28
// initialize director

CCDirector *pDirector = CCDirector::sharedDirector();

pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());



CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();



CCSize designSize = CCSizeMake(480,
320);

CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);

CCSize frameSize = CCEGLView::sharedOpenGLView()->getFrameSize();

CCSize resourceSize;

std::vector<std::string> searchPath;

if (frameSize.height >
768)

{

    searchPath.push_back("HDR");

    resourceSize = CCSizeMake(2048,
1536);

}

else if (frameSize.height >320)

{

    searchPath.push_back("HD");

    resourceSize = CCSizeMake(1024,
768);

}

else

{

    searchPath.push_back("SD");

    resourceSize = CCSizeMake(480,
320);

}

pDirector->setContentScaleFactor(resourceSize.height / designSize.height);

CCFileUtils::sharedFileUtils()->setSearchPaths(searchPath);
编译执行,能够看到熊愉快地漫步在屏幕上,例如以下图所看到的:

4.更改熊行走的方向。通过触摸屏幕,来控制熊的移动。打开HelloWorldScene.cpp文件,在init函数里面,凝视掉代码this->getBear()->runAction(this->getWalkAction());,这样一開始熊就不会移动。然后在代码最后加入例如以下代码:

1
this->setTouchEnabled(true);
加入例如以下方法: 
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66
void HelloWorld::registerWithTouchDispatcher()

{

    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);

}



bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)

{

    return true;

}



void HelloWorld::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)

{

    //1) Determine the touch location

    CCPoint touchLocation = this->convertTouchToNodeSpace(pTouch);



    //2) Set the desired velocity

    CCSize screenSize = CCDirector::sharedDirector()->getWinSize();

    float bearVelocity = screenSize.width /
3.0f;



    //3) Figure out the amount moved in X and Y

    CCPoint moveDifference = ccpSub(touchLocation,
this->getBear()->getPosition());



    //4) Figure out the actual length moved

    float distanceToMove = ccpLength(moveDifference);



    //5) Figure out how long it will take to move

    float moveDuration = distanceToMove / bearVelocity;



    //6) Flip the animation if necessary

    if (moveDifference.x <
0)

    {

        this->getBear()->setFlipX(false);

    }

    else

    {

        this->getBear()->setFlipX(true);

    }

   

    //7) Run the appropriate actions

    this->getBear()->stopAction(this->getMoveAction());



    if (!_bearMoving)

    {

        this->getBear()->runAction(this->getWalkAction());

    }

   

    this->setMoveAction(CCSequence::create(

        CCMoveTo::create(moveDuration, touchLocation),

        CCCallFunc::create(this, callfunc_selector(HelloWorld::bearMoveEnded)),

        NULL));



    this->getBear()->runAction(this->getMoveAction());

    _bearMoving = true;

}



void HelloWorld::cleanup()

{

    CC_SAFE_RELEASE_NULL(_moveAction);

    CCLayer::cleanup();

}



void HelloWorld::bearMoveEnded()

{

    this->getBear()->stopAction(this->getWalkAction());

    _bearMoving = false;

}
bearMoveEnded方法被调用时,不再移动,停止动画。ccTouchEnded方法说明例如以下:

  • ①确定触摸位置。转换触摸点到本地节点坐标。
  • ②设置期望的速度。设置熊的移动速度。
  • ③计算在x轴和y轴上的移动距离。
  • ④计算移动的真实长度。
  • ⑤计算移动的所需时间。
  • ⑥如有必须的话,则翻转动画。通过移动距离的x轴来推断熊是向左还是向右移动。仅仅需设置水平翻转,执行的动画也会跟着翻转。
  • ⑦执行适当的动作。首先,停止现有的移动动作,由于可能半途改变熊的目的地。接着,假设已经在移动了,就继续保持行走动作。最后,创建移动动作,指定移动的位置、移动的时间,和一个动作完毕时的回调,这个回调用来停止行走动作。变量_bearMoving用来推断是否正在移动中。

编译执行,触摸屏幕来移动熊,例如以下图所看到的:



參考资料:

很感谢以上资料,本样例源码附加资源下载地址:http://download.csdn.net/detail/yangshuo528/7411657

如文章存在错误之处,欢迎指出,以便改正。

转载+自练(莫喷)怎样在cocos2d 2.1.4里面使用动画和Texture Packer的更多相关文章

  1. 在cocos2d里面如何使用Texture Packer和像素格式来优化spritesheet

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  2. cocos2d js 利用texture packer生成sprite

    cc.spriteFrameCache.addSpriteFrames(res.winLose_plist,res.winLose_png); var frame = cc.spriteFrameCa ...

  3. Cocos2D iOS之旅:如何写一个敲地鼠游戏(四):创建TexturePacker自动脚本

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  4. [转载]TexturePacker 如何使用自带的加密功能及在cocos2dx中的使用

    在cocos2dx中使用纹理图集是非常节省资源的,在这里推荐 TexturePacker,而且 TexturePacker工具的加密接口也非常的好用,下面就来介绍一下... TexturePacker ...

  5. [一位菜鸟的COCOS-2D编程之路]精灵表单的制作以及简易动画的生成

    1.第一步:使用Zwoptex 制作精灵表单 2.制作的表单的名称为 cocos2Dpng,cocos2D.plist: 3.精灵的动画效果 主要分为五部分. // on "init&quo ...

  6. 面向基于英特尔&#174; 架构的 Android* 的 CoCos2D

    Cocos2D 是一款游戏引擎,可与从电脑到手机等多种设备配合使用. 该引擎支持丰富的特性,可帮助创建出色的 2D 游戏.它甚至包含具备全面功能的物理引擎. CoCos2D 的核心元素是基本动画元素( ...

  7. Spark源码系列(五)分布式缓存

    这一章想讲一下Spark的缓存是如何实现的.这个persist方法是在RDD里面的,所以我们直接打开RDD这个类. def persist(newLevel: StorageLevel): this. ...

  8. Python爬虫学习(6): 爬取MM图片

    为了有趣我们今天就主要去爬取以下MM的图片,并将其按名保存在本地.要爬取的网站为: 大秀台模特网 1. 分析网站 进入官网后我们发现有很多分类: 而我们要爬取的模特中的女模内容,点进入之后其网址为:h ...

  9. 第一篇(C#中?与??)

    不聊闲话,上干货~!(新手初上路,大牛莫喷,谢谢!) 先说?? 在C#中有个三元运算符  X= A==null?B:A 其中A为bool型.当A为空时,X的值为B;当A不为空时,X的值为A. 现在有个 ...

随机推荐

  1. SDUT oj 3005 打怪升级(内存搜索)

    当比赛一直纠缠骑2如何做一个非常大的数量,数组不开啊...后来他们发现自己很傻啊,该数不超过最大10什么,这个上限就是力量100什么.. .. 其它的就是记忆化搜索啊,还有就是加一点力量的瓶子当时就要 ...

  2. 简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)

    本文将简单介绍如何使用PowerMock和Mockito来mock1. 构造函数2. 静态函数3. 枚举实现的单例4. 选择参数值做为函数的返回值5. 在调用mock出来的方法中,改变方法参数的值 一 ...

  3. 物理卷操作命令:pvcreate,pvscan,pvdisplay.卷组操作命令:vgcreate,vgdisplay. (转)

    新硬盘创建LVM系统过程. 物理卷操作命令:pvcreate,pvscan,pvdisplay. 卷组操作命令:vgcreate,vgdisplay. 逻辑卷操作命令:lvcreate,lvdispl ...

  4. HDU - 5186 - zhx&#39;s submissions (精密塔尔苏斯)

    zhx's submissions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  5. Android虚拟机器学习总结Dalvik虚拟机创建进程和线程分析

    Dalvik调用一个成员函数时,虚拟机,假设发现,该成员函数是一个JNI办法,然后,它会直接跳转到其地址来运行.也就是说.JNI方法是直接在本地操作系统上运行的.而不是由Dalvik虚拟机解释器运行. ...

  6. 视频和音频播放的演示最简单的例子6:OpenGL广播YUV420P(T经exture,采用Shader)

    ===================================================== 最简单的视频和音频播放的演示样品系列列表: 最简单的视音频播放演示样例1:总述 最简单的视音 ...

  7. 82. NotesclientPrint相同的信息,以状态栏的问题

    这可能是一个小问题.但其他人也应该得到满足.在Notesclient使用LotusScript的Print当该语句是输出到状态栏,假设实际参数传递多次调用相同,状态栏将显示只有一次的信息. 例如: P ...

  8. CoffeeScript NgComponent

    Angular遇上CoffeeScript - NgComponent封装 CoffeeScript是基于JavaScript的一门扩展小巧语言,它需要编译成JavaScript,然后再运行与浏览器或 ...

  9. hdu4864Task(馋)

    主题链接: 啊哈哈.点我 题目: Task Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  10. 4.事务提交过程,交易的基本概念,Oracle交易周期,保存点savepoint,数据库的隔离级别

     事务提交过程 事务 基本概念 概念:一个或者多个DML语言组成 特点:要么都成功.要么都失败 事务的隔离性:多个client同一时候操作数据库的时候.要隔离它们的操作, 否则出现:脏读  不可反 ...