Learning Cocos2d-x for XNA(7)——让Sprite动起来
本讲将详细介绍Cocos2d-x游戏中动画Animate的创建方式,通过逐帧数组播放动画和创建动画集合播放动画,比较两者的异同,让Sprite动起来。
还是得创建两个文件AnimateLayer和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完整代码
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
修改代码后
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
修改后的代码
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文件代码
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完整代码
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 原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!