原文
http://zengrong.net/post/2006.htm
在 Cocos2d-x 中可以通过 CCAnimcation 来实现一个帧动画。在这种动画中,根据时间的流逝显示不同的纹理,形成动画。这就是我们平常所说的 逐帧动画 。本文将讨论这种动画的使用方法,以及如何利用现有的工具来简化使用和提高开发效率。
本文基于 Cocos2d-x 2.2.1
直接使用代码实现动画
当纹理作为单独的图像文件出现的时候,动画是这样实现的:
? View CodeCPP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
如果纹理处于plist文件中,则可以这样实现:
? View CodeCPP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
使用帧动画定义文件播放动画
使用代码实现动画的缺点是必须将动画的纹理名称硬编码到源码中,这样在修改纹理的时候必须重编编译程序。
如果使用帧动画定义文件,就可以避免这个问题,并得到更多的便利。
- format 1,定义了一个动画包含哪些帧以及帧纹理的名称,但是却并不能指定这些纹理从哪里加载。因此,我们必须提前加载将这些帧纹理使用的文件加载到缓存中。它可以为一个动画指定平均的帧延迟。
- format 2,可以直接指定需要的纹理文件的名称,也可以定义每帧的延迟。
CCAnimationCache::addAnimationsWithDictionary
负责解析这两种格式,并将它们转换成 CCAnimation ,同时保存在缓存中。
format 1 动画格式的播放
这是 format 1 格式的内容,文件名为 armatures.plist
。它定义了 dance_1/dance_2/dance_3
这3个动画,每个动画的帧延迟为0.2秒。
这个格式一看就懂,不需要详细介绍。
? View CodeXML
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 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>animations</key> <dict> <key>dance_1</key> <dict> <key>delay</key> <real>0.2</real> <key>frames</key> <array> <string>grossini_dance_01.png</string> <string>grossini_dance_02.png</string> <string>grossini_dance_03.png</string> <string>grossini_dance_04.png</string> <string>grossini_dance_05.png</string> <string>grossini_dance_06.png</string> <string>grossini_dance_07.png</string> <string>grossini_dance_08.png</string> <string>grossini_dance_09.png</string> <string>grossini_dance_10.png</string> <string>grossini_dance_11.png</string> <string>grossini_dance_12.png</string> <string>grossini_dance_13.png</string> <string>grossini_dance_14.png</string> </array> </dict> <key>dance_2</key> <dict> <key>delay</key> <real>0.2</real> <key>frames</key> <array> <string>grossini_dance_gray_01.png</string> <string>grossini_dance_gray_02.png</string> <string>grossini_dance_gray_03.png</string> <string>grossini_dance_gray_04.png</string> <string>grossini_dance_gray_05.png</string> <string>grossini_dance_gray_06.png</string> <string>grossini_dance_gray_07.png</string> <string>grossini_dance_gray_08.png</string> <string>grossini_dance_gray_09.png</string> <string>grossini_dance_gray_10.png</string> <string>grossini_dance_gray_11.png</string> <string>grossini_dance_gray_12.png</string> <string>grossini_dance_gray_13.png</string> <string>grossini_dance_gray_14.png</string> </array> </dict> <key>dance_3</key> <dict> <key>delay</key> <real>0.2</real> <key>frames</key> <array> <string>grossini_blue_01.png</string> <string>grossini_blue_02.png</string> <string>grossini_blue_03.png</string> <string>grossini_blue_04.png</string> </array> </dict> </dict> </dict> </plist> |
使用下面的代码将这3个动画串起来并连续播放:
? View CodeCPP
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 | CAnimationCache *animCache = CCAnimationCache::sharedAnimationCache(); //把动画定义文件载入缓存中 animCache->addAnimationsWithFile("animations/animations.plist"); //根据动画定义文件中的名称获取3个动画 CCAnimation *normal = animCache->animationByName("dance_1"); normal->setRestoreOriginalFrame(true); CCAnimation *dance_grey = animCache->animationByName("dance_2"); dance_grey->setRestoreOriginalFrame(true); CCAnimation *dance_blue = animCache->animationByName("dance_3"); dance_blue->setRestoreOriginalFrame(true); //创建Action进行播放 CCAnimate *animN = CCAnimate::create(normal); CCAnimate *animG = CCAnimate::create(dance_grey); CCAnimate *animB = CCAnimate::create(dance_blue); CCSequence *seq = CCSequence::create(animN, animG, animB, NULL); //创建一个不带纹理的精灵 CCSprite *grossini = CCSprite::create(); //获取一个精灵帧,设置成精灵的第1帧 CCSpriteFrame *frame = frameCache->spriteFrameByName("grossini_dance_01.png"); grossini->setDisplayFrame(frame); addChild(grossini); //播放动画 grossini->runAction(seq); |
format 2 动画格式plist文件内容
这是 format 2 格式的内容,文件名为 armatures-2.plist
。它定义了 dance_1
这个动画。其中:
- delayPerUnit 定义的就是每帧之间的间隔,是 0.2 秒。
- delayUnits 定义了每帧的延迟值,它会覆盖 delayPerUnit 的定义。实际上,动画持续的时间,就是 所有帧的 delayUnits 的和乘以 delayPerUnit 。
- notification 中定义的值会保存在 CCAnimationFrame 中。这些值的本意是在动画播放到设置值的帧时,触发一些事件。但是在 Cocos2d-x 2.2.1 中,这个事件触发并没有实现。
- properties 定义了动画格式的版本以及这个动画中使用的帧来自于哪些纹理。
? View CodeXML
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>animations</key> <dict> <key>dance_1</key> <dict> <key>delayPerUnit</key> <real>0.2</real> <key>restoreOriginalFrame</key> <true/> <key>loops</key> <integer>2</integer> <key>frames</key> <array> <dict> <key>spriteframe</key> <string>grossini_dance_01.png</string> <key>delayUnits</key> <integer>1</integer> <key>notification</key> <dict> <key>firstframe</key> <true/> </dict> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_02.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_03.png</string> <key>delayUnits</key> <real>0.5</real> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_04.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_05.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_06.png</string> <key>delayUnits</key> <integer>1</integer> <key>notification</key> <dict> <key>key1</key> <integer>1234</integer> <key>key2</key> <false/> </dict> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_07.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_08.png</string> <key>delayUnits</key> <integer>2</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_09.png</string> <key>delayUnits</key> <real>0.5</real> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_10.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_11.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_12.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_13.png</string> <key>delayUnits</key> <integer>1</integer> </dict> <dict> <key>spriteframe</key> <string>grossini_dance_14.png</string> <key>delayUnits</key> <integer>1</integer> <key>notification</key> <dict> <key>lastframe</key> <true/> </dict> </dict> </array> </dict> </dict> <key>properties</key> <dict> <key>spritesheets</key> <array> <string>animations/grossini.plist</string> <string>animations/grossini_blue.plist</string> <string>animations/grossini_family.plist</string> </array> <key>format</key> <integer>2</integer> </dict> </dict> </plist> |
使用下面的代码播放这个动画:
? View CodeCPP
1 2 3 4 5 6 7 8 9 10 | |