Cocos2d-x 中的帧动画
在 Cocos2d-x 中可以通过 CCAnimcation 来实现一个帧动画。在这种动画中,根据时间的流逝显示不同的纹理,形成动画。这就是我们平常所说的 逐帧动画。
本文将讨论这种动画的使用方法,以及如何利用现有的工具来简化使用和提高开发效率。
本文基于 Cocos2d-x 2.2.1
1. 直接使用代码实现动画
当纹理作为单独的图像文件出现的时候,动画是这样实现的:
1//建立一个帧动画,填充14个纹理
2CCAnimation* animation = CCAnimation::create();
3for( int i=1;i<15;i++)
4{
5 char szName[100] = {0};
6 sprintf(szName, "Images/grossini_dance_%02d.png", i);
7 animation->addSpriteFrameWithFileName(szName);
8}
9//在2.8秒中显示14帧,计算延迟
10animation->setDelayPerUnit(2.8f / 14.0f);
11animation->setRestoreOriginalFrame(true);
12
13CCAnimate* action = CCAnimate::create(animation);
14
15// grossini 是一个CCSprite,使用它播放一个自动回绕的动画
16grossini->runAction(CCSequence::create(action, action->reverse(), NULL));
如果纹理处于plist文件中,则可以这样实现:
1//将纹理提前加入精灵帧缓存
2CCSpriteFrameCache *frameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
3frameCache->addSpriteFramesWithFile("animations/grossini.plist");
4
5//建立15个元素的精灵帧数组
6CCArray* animFrames = CCArray::createWithCapacity(15);
7char str[100] = {0};
8for(int i = 1; i < 15; i++)
9{
10 sprintf(str, "grossini_dance_%02d.png",i);
11 CCSpriteFrame *frame = frameCache->spriteFrameByName(str);
12 animFrames->addObject(frame);
13}
14
15CCAnimation *animation = CCAnimation::createWithSpriteFrames(animFrames, 0.2f);
16CCAnimate *anim = CCAnimate::create(animation);
17
18//创建一个精灵用于显示动画
19CCSprite *grossini = CCSprite::create();
20CCSpriteFrame *frame = frameCache->spriteFrameByName("grossini_dance_01.png");
21grossini->setDisplayFrame(frame);
22
23//播放一个永久循环的动画
24grossini->runAction(CCRepeatForever::create(anim))
2. 使用帧动画定义文件播放动画
使用代码实现动画的缺点是必须将动画的纹理名称硬编码到源码中,这样在修改纹理的时候必须重编编译程序。
如果使用帧动画定义文件,就可以避免这个问题,并得到更多的便利。
这种文件有2种格式:
- format 1,定义了一个动画包含哪些帧以及帧纹理的名称,但是却并不能指定这些纹理从哪里加载。因此,我们必须提前加载将这些帧纹理使用的文件加载到缓存中。它可以为一个动画指定平均的帧延迟。
- format 2,可以直接指定需要的纹理文件的名称,也可以定义每帧的延迟。
CCAnimationCache::addAnimationsWithDictionary
负责解析这两种格式,并将它们转换成 CCAnimation ,同时保存在缓存中。
2.1 format 1 动画格式的播放
这是 format 1 格式的内容,文件名为 armatures.plist
。它定义了 dance_1/dance_2/dance_3
这3个动画,每个动画的帧延迟为0.2秒。
这个格式一看就懂,不需要详细介绍。
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<dict>
5 <key>animations</key>
6 <dict>
7 <key>dance_1</key>
8 <dict>
9 <key>delay</key>
10 <real>0.2</real>
11 <key>frames</key>
12 <array>
13 <string>grossini_dance_01.png</string>
14 <string>grossini_dance_02.png</string>
15 <string>grossini_dance_03.png</string>
16 <string>grossini_dance_04.png</string>
17 <string>grossini_dance_05.png</string>
18 <string>grossini_dance_06.png</string>
19 <string>grossini_dance_07.png</string>
20 <string>grossini_dance_08.png</string>
21 <string>grossini_dance_09.png</string>
22 <string>grossini_dance_10.png</string>
23 <string>grossini_dance_11.png</string>
24 <string>grossini_dance_12.png</string>
25 <string>grossini_dance_13.png</string>
26 <string>grossini_dance_14.png</string>
27 </array>
28 </dict>
29 <key>dance_2</key>
30 <dict>
31 <key>delay</key>
32 <real>0.2</real>
33 <key>frames</key>
34 <array>
35 <string>grossini_dance_gray_01.png</string>
36 <string>grossini_dance_gray_02.png</string>
37 <string>grossini_dance_gray_03.png</string>
38 <string>grossini_dance_gray_04.png</string>
39 <string>grossini_dance_gray_05.png</string>
40 <string>grossini_dance_gray_06.png</string>
41 <string>grossini_dance_gray_07.png</string>
42 <string>grossini_dance_gray_08.png</string>
43 <string>grossini_dance_gray_09.png</string>
44 <string>grossini_dance_gray_10.png</string>
45 <string>grossini_dance_gray_11.png</string>
46 <string>grossini_dance_gray_12.png</string>
47 <string>grossini_dance_gray_13.png</string>
48 <string>grossini_dance_gray_14.png</string>
49 </array>
50 </dict>
51 <key>dance_3</key>
52 <dict>
53 <key>delay</key>
54 <real>0.2</real>
55 <key>frames</key>
56 <array>
57 <string>grossini_blue_01.png</string>
58 <string>grossini_blue_02.png</string>
59 <string>grossini_blue_03.png</string>
60 <string>grossini_blue_04.png</string>
61 </array>
62 </dict>
63 </dict>
64</dict>
65</plist>
使用下面的代码将这3个动画串起来并连续播放:
1CAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();
2
3//把动画定义文件载入缓存中
4animCache->addAnimationsWithFile("animations/animations.plist");
5
6//根据动画定义文件中的名称获取3个动画
7CCAnimation *normal = animCache->animationByName("dance_1");
8normal->setRestoreOriginalFrame(true);
9CCAnimation *dance_grey = animCache->animationByName("dance_2");
10dance_grey->setRestoreOriginalFrame(true);
11CCAnimation *dance_blue = animCache->animationByName("dance_3");
12dance_blue->setRestoreOriginalFrame(true);
13
14//创建Action进行播放
15CCAnimate *animN = CCAnimate::create(normal);
16CCAnimate *animG = CCAnimate::create(dance_grey);
17CCAnimate *animB = CCAnimate::create(dance_blue);
18CCSequence *seq = CCSequence::create(animN, animG, animB, NULL);
19
20//创建一个不带纹理的精灵
21CCSprite *grossini = CCSprite::create();
22//获取一个精灵帧,设置成精灵的第1帧
23CCSpriteFrame *frame = frameCache->spriteFrameByName("grossini_dance_01.png");
24grossini->setDisplayFrame(frame);
25addChild(grossini);
26
27//播放动画
28grossini->runAction(seq);
2.2 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 定义了动画格式的版本以及这个动画中使用的帧来自于哪些纹理。
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<dict>
5 <key>animations</key>
6 <dict>
7 <key>dance_1</key>
8 <dict>
9 <key>delayPerUnit</key>
10 <real>0.2</real>
11 <key>restoreOriginalFrame</key>
12 <true/>
13 <key>loops</key>
14 <integer>2</integer>
15 <key>frames</key>
16 <array>
17 <dict>
18 <key>spriteframe</key>
19 <string>grossini_dance_01.png</string>
20 <key>delayUnits</key>
21 <integer>1</integer>
22 <key>notification</key>
23 <dict>
24 <key>firstframe</key>
25 <true/>
26 </dict>
27 </dict>
28 <dict>
29 <key>spriteframe</key>
30 <string>grossini_dance_02.png</string>
31 <key>delayUnits</key>
32 <integer>1</integer>
33 </dict>
34 <dict>
35 <key>spriteframe</key>
36 <string>grossini_dance_03.png</string>
37 <key>delayUnits</key>
38 <real>0.5</real>
39 </dict>
40 <dict>
41 <key>spriteframe</key>
42 <string>grossini_dance_04.png</string>
43 <key>delayUnits</key>
44 <integer>1</integer>
45 </dict>
46 <dict>
47 <key>spriteframe</key>
48 <string>grossini_dance_05.png</string>
49 <key>delayUnits</key>
50 <integer>1</integer>
51 </dict>
52 <dict>
53 <key>spriteframe</key>
54 <string>grossini_dance_06.png</string>
55 <key>delayUnits</key>
56 <integer>1</integer>
57 <key>notification</key>
58 <dict>
59 <key>key1</key>
60 <integer>1234</integer>
61 <key>key2</key>
62 <false/>
63 </dict>
64 </dict>
65 <dict>
66 <key>spriteframe</key>
67 <string>grossini_dance_07.png</string>
68 <key>delayUnits</key>
69 <integer>1</integer>
70 </dict>
71 <dict>
72 <key>spriteframe</key>
73 <string>grossini_dance_08.png</string>
74 <key>delayUnits</key>
75 <integer>2</integer>
76 </dict>
77 <dict>
78 <key>spriteframe</key>
79 <string>grossini_dance_09.png</string>
80 <key>delayUnits</key>
81 <real>0.5</real>
82 </dict>
83 <dict>
84 <key>spriteframe</key>
85 <string>grossini_dance_10.png</string>
86 <key>delayUnits</key>
87 <integer>1</integer>
88 </dict>
89 <dict>
90 <key>spriteframe</key>
91 <string>grossini_dance_11.png</string>
92 <key>delayUnits</key>
93 <integer>1</integer>
94 </dict>
95 <dict>
96 <key>spriteframe</key>
97 <string>grossini_dance_12.png</string>
98 <key>delayUnits</key>
99 <integer>1</integer>
100 </dict>
101 <dict>
102 <key>spriteframe</key>
103 <string>grossini_dance_13.png</string>
104 <key>delayUnits</key>
105 <integer>1</integer>
106 </dict>
107 <dict>
108 <key>spriteframe</key>
109 <string>grossini_dance_14.png</string>
110 <key>delayUnits</key>
111 <integer>1</integer>
112 <key>notification</key>
113 <dict>
114 <key>lastframe</key>
115 <true/>
116 </dict>
117 </dict>
118 </array>
119 </dict>
120 </dict>
121 <key>properties</key>
122 <dict>
123 <key>spritesheets</key>
124 <array>
125 <string>animations/grossini.plist</string>
126 <string>animations/grossini_blue.plist</string>
127 <string>animations/grossini_family.plist</string>
128 </array>
129 <key>format</key>
130 <integer>2</integer>
131 </dict>
132</dict>
133</plist>
使用下面的代码播放这个动画:
1//解析动画定义文件,将动画载入缓存
2CCAnimationCache *cache = CCAnimationCache::sharedAnimationCache();
3cache->addAnimationsWithFile("animations/animations-2.plist");
4
5//创建动画
6CCAnimation *animation = cache->animationByName("dance_1");
7CCAnimate* action = CCAnimate::create(animation);
8
9//播放一个回绕的动画,grossini是一个已存在的精灵
10grossini->runAction(CCSequence::create(action, action->reverse(), NULL));
(全文完)
- 文章ID:2006
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/explain-cocos2d-x-plist-file-format/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。