Learning Cocos2d-x for XNA(7)——让Sprite动起来

本讲将详细介绍Cocos2d-x游戏中动画Animate的创建方式,通过逐帧数组播放动画和创建动画集合播放动画,比较两者的异同,让Sprite动起来。

还是得创建两个文件AnimateLayer和AnimateScene

AnimateScene

AnimateScene
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using cocos2d;
 6 
 7 namespace LearningCocos2d_xForXNA.Classes
 8 {
 9     class AnimateScene:CCScene
10     {
11         public AnimateScene()
12         {
13             CCLayer _animateLayer =new AnimateLayer();
14             this.addChild(_animateLayer);
15         }
16     }
17 }

通过逐帧数组播放动画

动画是通过逐帧连续播放图像而形成的动作画面。

既然是逐帧动画,细化话后,即是单帧,通过记录单帧信息,然后再将单帧连续起来,即是逐帧动画。

前期准备

内容管道(Content)创建文件夹img/Wolf/Sprite,并在其中添加以下贴图(740*105)

(素材来源于《狼来了》,仅为学习方便,请勿用于商业用途)

在AnimateLayer层完成以下步骤

1.读取2D纹理信息

CCTexture2D texture = CCTextureCache.sharedTextureCache().addImage("img/Wolf/Sprite/aoao");//2D纹理

值得注意的是逐帧动画,只能将贴图放置同一张大图片下,否则不能形成动画。

2.记录单帧信息

 1             // 记录单帧信息
 2             CCSpriteFrame frame0 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 0, 0, 74, 105));
 3             CCSpriteFrame frame1 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 1, 0, 74, 105));
 4             CCSpriteFrame frame2 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 2, 0, 74, 105));
 5             CCSpriteFrame frame3 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 3, 0, 74, 105));
 6             CCSpriteFrame frame4 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 4, 0, 74, 105));
 7             CCSpriteFrame frame5 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 5, 0, 74, 105));
 8             CCSpriteFrame frame6 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 6, 0, 74, 105));
 9             CCSpriteFrame frame7 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 7, 0, 74, 105));
10             CCSpriteFrame frame8 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 8, 0, 74, 105));
11             CCSpriteFrame frame9 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 9, 0, 74, 105));

 3.设置起始帧

1  // 起始帧
2             CCSprite sprite = CCSprite.spriteWithSpriteFrame(frame0);
3             sprite.position = (new CCPoint(s.width / 2, s.height / 2));
4             addChild(sprite);

4.生成逐帧数组

 1             //生成逐帧数组
 2             List<CCSpriteFrame> animFrames = new List<CCSpriteFrame>(10);
 3             animFrames.Add(frame0);
 4             animFrames.Add(frame1);
 5             animFrames.Add(frame2);
 6             animFrames.Add(frame3);
 7             animFrames.Add(frame4);
 8             animFrames.Add(frame5);
 9             animFrames.Add(frame6);
10             animFrames.Add(frame7);
11             animFrames.Add(frame8);
12             animFrames.Add(frame9);

 5.执行动画

1             //动画Animate
2             CCAnimation animation = CCAnimation.animationWithFrames(animFrames, 0.2f);//Animation动画信息
3             CCAnimate animate = CCAnimate.actionWithAnimation(animation, false);
4             CCActionInterval seq = (CCActionInterval)(CCSequence.actions(animate));//动画间隔
5 
6             sprite.runAction(CCRepeatForever.actionWithAction(seq));

AnimateLayer完整代码

AnimateLayer
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using cocos2d;
 6 
 7 namespace LearningCocos2d_xForXNA.Classes
 8 {
 9     class AnimateLayer:CCLayer
10     {
11         public AnimateLayer()
12         {
13             CCDirector.sharedDirector().deviceOrientation = ccDeviceOrientation.kCCDeviceOrientationPortraitUpsideDown;//设置朝向,竖屏
14 
15             #region 单帧动画CCSpriteFrame
16             CCSize s = CCDirector.sharedDirector().getWinSize();
17             CCTexture2D texture = CCTextureCache.sharedTextureCache().addImage("img/Wolf/Sprite/aoao");//2D纹理
18             // 记录单帧信息
19             CCSpriteFrame frame0 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 0, 0, 74, 105));
20             CCSpriteFrame frame1 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 1, 0, 74, 105));
21             CCSpriteFrame frame2 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 2, 0, 74, 105));
22             CCSpriteFrame frame3 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 3, 0, 74, 105));
23             CCSpriteFrame frame4 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 4, 0, 74, 105));
24             CCSpriteFrame frame5 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 5, 0, 74, 105));
25             CCSpriteFrame frame6 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 6, 0, 74, 105));
26             CCSpriteFrame frame7 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 7, 0, 74, 105));
27             CCSpriteFrame frame8 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 8, 0, 74, 105));
28             CCSpriteFrame frame9 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 9, 0, 74, 105));
29             // 起始帧
30             CCSprite sprite = CCSprite.spriteWithSpriteFrame(frame0);
31             sprite.position = (new CCPoint(s.width / 2, s.height / 2));
32             addChild(sprite);
33             //生成逐帧数组
34             List<CCSpriteFrame> animFrames = new List<CCSpriteFrame>(10);
35             animFrames.Add(frame0);
36             animFrames.Add(frame1);
37             animFrames.Add(frame2);
38             animFrames.Add(frame3);
39             animFrames.Add(frame4);
40             animFrames.Add(frame5);
41             animFrames.Add(frame6);
42             animFrames.Add(frame7);
43             animFrames.Add(frame8);
44             animFrames.Add(frame9);
45             //动画Animate
46             CCAnimation animation = CCAnimation.animationWithFrames(animFrames, 0.2f);//Animation动画信息
47             CCAnimate animate = CCAnimate.actionWithAnimation(animation, false);
48             CCActionInterval seq = (CCActionInterval)(CCSequence.actions(animate));//动画间隔
49 
50             sprite.runAction(CCRepeatForever.actionWithAction(seq));
51             #endregion
52         }
53     }
54 }

 显示效果,即看见Sprite动起来了

 创建动画帧集合

 动画帧集合即是导入贴图文件.png和导入贴图文件的配置文件.plist

前面都是通过一张图片或图片的部分创建精灵并将其加入到场景中,这样导致的结果是每次添加精灵时,都要逐个渲染精灵,性能低下,一旦过多精灵渲染,将会影响效率。

精灵批处理

使用CCSpriteBatchNode来批处理这些精灵就可以避免帧率的下降。

创建CCSpriteBatchNode的方法

1         public static CCSpriteBatchNode batchNodeWithFile(string fileImage);
2         public static CCSpriteBatchNode batchNodeWithFile(string fileImage, int capacity);
3         public static CCSpriteBatchNode batchNodeWithTexture(CCTexture2D tex);
4         public static CCSpriteBatchNode batchNodeWithTexture(CCTexture2D tex, int capacity);

其中capacity是子节点的数量,当然,不显式设置子节点的数量的话,系统会使用默认值29,在运行时如果超过空间了,会增加33%的容量。

CCSpriteBatchNode有一个限制,就是所使用的图片必须来自同一个文件,如果使用一张图片来创建精灵,你将不能指定精灵的深度,这样,所有的精灵都必须在同一渲染层,不过你可以使用贴图集来避免这个问题,如果你的所有贴图都在同一个文件里,那么你只需创建一个CCSpriteBatchNode就可以了。贴图的大小必须满足2的n次方。

前期准备

添加对cocos2d-x.framework的引用

新建文件夹Text,在文件下新增内容处理器TextProcessor

 修改代码后

TextProcessor
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using Microsoft.Xna.Framework;
 5 using Microsoft.Xna.Framework.Graphics;
 6 using Microsoft.Xna.Framework.Content.Pipeline;
 7 using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
 8 using Microsoft.Xna.Framework.Content.Pipeline.Processors;
 9 
10 // TODO: 将这些项替换为处理器输入和输出类型。
11 using TInput = System.String;
12 using TOutput = cocos2d.Framework.CCContent;
13 
14 namespace FontProcessor.Text
15 {
16     /// <summary>
17     /// 此类将由 XNA Framework 内容管道实例化,
18     /// 以便将自定义处理应用于内容数据,将对象转换用于类型 TInput 到
19     /// 类型 TOnput 的改变。如果处理器希望改变数据但不更改其类型,
20     /// 输入和输出类型可以相同。
21     ///
22     /// 这应当属于内容管道扩展库项目的一部分。
23     ///
24     /// TODO: 更改 ContentProcessor 属性以为此处理器指定
25     /// 正确的显示名称。
26     /// </summary>
27     [ContentProcessor(DisplayName = "TextProcessor")]
28     public class TextProcessor : ContentProcessor<TInput, TOutput>
29     {
30         public override TOutput Process(TInput input, ContentProcessorContext context)
31         {
32             TOutput result = new TOutput();
33             result.Content = input;
34 
35             return result;
36         }
37     }
38 }

同样的方法生成内容导入程序TextImporter

修改后的代码

TextImporter
 1 using System.Linq;
 2 using Microsoft.Xna.Framework;
 3 using Microsoft.Xna.Framework.Graphics;
 4 using Microsoft.Xna.Framework.Content.Pipeline;
 5 using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
 6 
 7 // TODO: 将此项替换为要导入的类型。
 8 using TImport = System.String;
 9 
10 namespace FontProcessor.Text
11 {
12     /// <summary>
13     /// 此类将由 XNA Framework 内容管道实例化,
14     /// 以将磁盘文件导入为指定类型 TImport。
15     /// 
16     /// 这应当属于内容管道扩展库项目的一部分。
17     /// 
18     /// TODO: 更改 ContentImporter 属性以指定此导入程序的
19     /// 正确文件扩展名、显示名和默认处理器。
20     /// </summary>
21     [ContentImporter(".*", DisplayName = "Text Importer", DefaultProcessor = "TextImporter")]
22     public class TextImporter : ContentImporter<TImport>
23     {
24         public override TImport Import(string filename, ContentImporterContext context)
25         {
26             // TODO: 将指定的文件读入所导入类型的一个实例中。
27             return System.IO.File.ReadAllText(filename);
28         }
29     }
30 }

重新生成一下FontProcessor

打开TexturePackerGUI工具(具体用法自行解决),将所有的素材图片拖放至Sprites中。

之后publish,即可得到两个文件plist和png图。

(素材来源于《狼来了》,仅为学习方便,请勿用于商业用途)

 plist文件代码

aoao.plist
  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <plist version="1.0">
  3     <dict>
  4         <key>frames</key>
  5         <dict>
  6             <key>aoao.png</key>
  7             <dict>
  8                 <key>frame</key>
  9                 <string>{{2,2},{734,105}}</string>
 10                 <key>offset</key>
 11                 <string>{0,0}</string>
 12                 <key>sourceSize</key>
 13                 <string>{740,105}</string>
 14             </dict>
 15             <key>aoao1.png</key>
 16             <dict>
 17                 <key>frame</key>
 18                 <string>{{360,109},{68,97}}</string>
 19                 <key>offset</key>
 20                 <string>{3,-4}</string>
 21                 <key>sourceSize</key>
 22                 <string>{74,105}</string>
 23             </dict>
 24             <key>aoao10.png</key>
 25             <dict>
 26                 <key>frame</key>
 27                 <string>{{220,109},{68,99}}</string>
 28                 <key>offset</key>
 29                 <string>{3,-3}</string>
 30                 <key>sourceSize</key>
 31                 <string>{74,105}</string>
 32             </dict>
 33             <key>aoao2.png</key>
 34             <dict>
 35                 <key>frame</key>
 36                 <string>{{290,109},{68,97}}</string>
 37                 <key>offset</key>
 38                 <string>{3,-4}</string>
 39                 <key>sourceSize</key>
 40                 <string>{74,105}</string>
 41             </dict>
 42             <key>aoao3.png</key>
 43             <dict>
 44                 <key>frame</key>
 45                 <string>{{498,109},{66,95}}</string>
 46                 <key>offset</key>
 47                 <string>{3,-5}</string>
 48                 <key>sourceSize</key>
 49                 <string>{74,105}</string>
 50             </dict>
 51             <key>aoao4.png</key>
 52             <dict>
 53                 <key>frame</key>
 54                 <string>{{430,109},{66,95}}</string>
 55                 <key>offset</key>
 56                 <string>{3,-5}</string>
 57                 <key>sourceSize</key>
 58                 <string>{74,105}</string>
 59             </dict>
 60             <key>aoao5.png</key>
 61             <dict>
 62                 <key>frame</key>
 63                 <string>{{566,109},{64,93}}</string>
 64                 <key>offset</key>
 65                 <string>{3,-6}</string>
 66                 <key>sourceSize</key>
 67                 <string>{74,105}</string>
 68             </dict>
 69             <key>aoao6.png</key>
 70             <dict>
 71                 <key>frame</key>
 72                 <string>{{566,109},{64,93}}</string>
 73                 <key>offset</key>
 74                 <string>{3,-6}</string>
 75                 <key>sourceSize</key>
 76                 <string>{74,105}</string>
 77             </dict>
 78             <key>aoao7.png</key>
 79             <dict>
 80                 <key>frame</key>
 81                 <string>{{148,109},{70,105}}</string>
 82                 <key>offset</key>
 83                 <string>{-1,0}</string>
 84                 <key>sourceSize</key>
 85                 <string>{74,105}</string>
 86             </dict>
 87             <key>aoao8.png</key>
 88             <dict>
 89                 <key>frame</key>
 90                 <string>{{2,109},{72,105}}</string>
 91                 <key>offset</key>
 92                 <string>{-1,0}</string>
 93                 <key>sourceSize</key>
 94                 <string>{74,105}</string>
 95             </dict>
 96             <key>aoao9.png</key>
 97             <dict>
 98                 <key>frame</key>
 99                 <string>{{76,109},{70,105}}</string>
100                 <key>offset</key>
101                 <string>{-1,0}</string>
102                 <key>sourceSize</key>
103                 <string>{74,105}</string>
104             </dict>
105         </dict>
106         <key>metadata</key>
107         <dict>
108             <key>format</key>
109             <integer>1</integer>
110             <key>realTextureFileName</key>
111             <string>aoao.png</string>
112             <key>size</key>
113             <string>{1024,256}</string>
114             <key>smartupdate</key>
115             <string>$TexturePacker:SmartUpdate:04e5a7f7e0f4e21dfa7ecb6ac7f51df1$</string>
116             <key>textureFileName</key>
117             <string>aoao.png</string>
118         </dict>
119     </dict>
120 </plist>

将plist(aoao.plist)文件放置到我们的工程文件文件夹plist下,png(aoao.png)放置plist/images中(注意文件的位置)。

 点中aoao.plist文件,修改属性。

在AnimateLayer层完成以下步骤

1. 创建批处理节点,读取plist文件

CCSpriteBatchNode提供四个常规方法读取文件

1         public static CCSpriteBatchNode batchNodeWithFile(string fileImage);
2         public static CCSpriteBatchNode batchNodeWithFile(string fileImage, int capacity);
3         public static CCSpriteBatchNode batchNodeWithTexture(CCTexture2D tex);
4         public static CCSpriteBatchNode batchNodeWithTexture(CCTexture2D tex, int capacity);
5 代码
6             // 创建批处理节点,读取plist文件
7             CCSpriteBatchNode batch = CCSpriteBatchNode.batchNodeWithFile("plist/images/aoao");//批处理节点贴图
8             addChild(batch, 0, 1);
9             CCSpriteFrameCache.sharedSpriteFrameCache().addSpriteFramesWithFile("plist/aoao");//读取plsit文件

2. 起始精灵

1             //起始精灵
2             CCSprite sprite1 = CCSprite.spriteWithSpriteFrameName("aoao1.png");
3             sprite1.position = (new CCPoint(s.width / 3, s.height / 2));
4             batch.addChild(sprite1);

其中"aoao.png"为aoao.plist中的节点纹理。

3. 创建逐帧数组

 1             List<CCSpriteFrame> animFrames = new List<CCSpriteFrame>();
 2             string str = "";
 3             for (int i = 2; i < 11; i++)
 4             {
 5                 string temp = "";
 6                 temp = i.ToString();
 7                 str = string.Format("aoao{0}.png", temp);
 8                 CCSpriteFrame frame = CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName(str);
 9                 animFrames.Add(frame);
10             }

4. 动画Animate

1             CCAnimation animation = CCAnimation.animationWithFrames(animFrames, 0.2f);//Animation动画信息
2             sprite1.runAction(CCRepeatForever.actionWithAction(CCAnimate.actionWithAnimation(animation, false)));//执行动画

AnimateLayer完整代码

AnimateLayer
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using cocos2d;
 6 
 7 namespace LearningCocos2d_xForXNA.Classes
 8 {
 9     class AnimateLayer:CCLayer
10     {
11         public AnimateLayer()
12         {
13             CCDirector.sharedDirector().deviceOrientation = ccDeviceOrientation.kCCDeviceOrientationPortraitUpsideDown;//设置朝向,竖屏
14 
15             #region 单帧动画CCSpriteFrame
16             //CCSize s = CCDirector.sharedDirector().getWinSize();
17             //CCTexture2D texture = CCTextureCache.sharedTextureCache().addImage("img/Wolf/Sprite/aoao");//2D纹理
18             //// 记录单帧信息
19             //CCSpriteFrame frame0 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 0, 0, 74, 105));
20             //CCSpriteFrame frame1 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 1, 0, 74, 105));
21             //CCSpriteFrame frame2 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 2, 0, 74, 105));
22             //CCSpriteFrame frame3 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 3, 0, 74, 105));
23             //CCSpriteFrame frame4 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 4, 0, 74, 105));
24             //CCSpriteFrame frame5 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 5, 0, 74, 105));
25             //CCSpriteFrame frame6 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 6, 0, 74, 105));
26             //CCSpriteFrame frame7 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 7, 0, 74, 105));
27             //CCSpriteFrame frame8 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 8, 0, 74, 105));
28             //CCSpriteFrame frame9 = CCSpriteFrame.frameWithTexture(texture, new CCRect(74 * 9, 0, 74, 105));
29             //// 起始帧
30             //CCSprite sprite = CCSprite.spriteWithSpriteFrame(frame0);
31             //sprite.position = (new CCPoint(s.width / 2, s.height / 2));
32             //addChild(sprite);
33             ////生成逐帧数组
34             //List<CCSpriteFrame> animFrames = new List<CCSpriteFrame>(10);
35             //animFrames.Add(frame0);
36             //animFrames.Add(frame1);
37             //animFrames.Add(frame2);
38             //animFrames.Add(frame3);
39             //animFrames.Add(frame4);
40             //animFrames.Add(frame5);
41             //animFrames.Add(frame6);
42             //animFrames.Add(frame7);
43             //animFrames.Add(frame8);
44             //animFrames.Add(frame9);
45             ////动画Animate
46             //CCAnimation animation = CCAnimation.animationWithFrames(animFrames, 0.2f);//Animation动画信息
47             //CCAnimate animate = CCAnimate.actionWithAnimation(animation, false);
48             //CCActionInterval seq = (CCActionInterval)(CCSequence.actions(animate));//动画间隔
49 
50             //sprite.runAction(CCRepeatForever.actionWithAction(seq));
51             #endregion
52 
53             #region 动画帧集合
54             CCSize s = CCDirector.sharedDirector().getWinSize();
55             // 创建批处理节点,读取plist文件
56             CCSpriteBatchNode batch = CCSpriteBatchNode.batchNodeWithFile("plist/images/aoao");//批处理节点贴图
57             addChild(batch, 0, 1);
58             CCSpriteFrameCache.sharedSpriteFrameCache().addSpriteFramesWithFile("plist/aoao");//读取plsit文件
59             //起始精灵
60             CCSprite sprite1 = CCSprite.spriteWithSpriteFrameName("aoao1.png");
61             sprite1.position = (new CCPoint(s.width / 3, s.height / 2));
62             batch.addChild(sprite1);
63             // 创建逐帧数组
64             List<CCSpriteFrame> animFrames = new List<CCSpriteFrame>();
65             string str = "";
66             for (int i = 2; i < 11; i++)
67             {
68                 string temp = "";
69                 temp = i.ToString();
70                 str = string.Format("aoao{0}.png", temp);
71                 CCSpriteFrame frame = CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName(str);
72                 animFrames.Add(frame);
73             }
74             //动画Animate
75             CCAnimation animation = CCAnimation.animationWithFrames(animFrames, 0.2f);//Animation动画信息
76             sprite1.runAction(CCRepeatForever.actionWithAction(CCAnimate.actionWithAnimation(animation, false)));//执行动画
77             #endregion
78         }
79     }
80 }

显示效果,同样可以得到一样的效果

 本实例源码下载

著作权声明:本文由http://www.cnblogs.com/suguoqiang 原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

posted @ 2013-02-04 13:59  Ghost Soar  阅读(1846)  评论(2编辑  收藏  举报