本讲将详细介绍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:CCScene10 {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 ListanimFrames = new List (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 //动画Animate2 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:CCLayer10 {11 public AnimateLayer()12 {13 CCDirector.sharedDirector().deviceOrientation = ccDeviceOrientation.kCCDeviceOrientationPortraitUpsideDown;//设置朝向,竖屏14 15 #region 单帧动画CCSpriteFrame16 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 ListanimFrames = new List (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 //动画Animate46 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 #endregion52 }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.Text15 {16 ///17 /// 此类将由 XNA Framework 内容管道实例化,18 /// 以便将自定义处理应用于内容数据,将对象转换用于类型 TInput 到19 /// 类型 TOnput 的改变。如果处理器希望改变数据但不更改其类型,20 /// 输入和输出类型可以相同。21 ///22 /// 这应当属于内容管道扩展库项目的一部分。23 ///24 /// TODO: 更改 ContentProcessor 属性以为此处理器指定25 /// 正确的显示名称。26 /// 27 [ContentProcessor(DisplayName = "TextProcessor")]28 public class TextProcessor : ContentProcessor29 {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.Text11 {12 ///13 /// 此类将由 XNA Framework 内容管道实例化,14 /// 以将磁盘文件导入为指定类型 TImport。15 /// 16 /// 这应当属于内容管道扩展库项目的一部分。17 /// 18 /// TODO: 更改 ContentImporter 属性以指定此导入程序的19 /// 正确文件扩展名、显示名和默认处理器。20 /// 21 [ContentImporter(".*", DisplayName = "Text Importer", DefaultProcessor = "TextImporter")]22 public class TextImporter : ContentImporter23 {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 23 4 120frames 56 106aoao.png 78 15frame 9{ {2,2},{734,105}} 10offset 11{0,0} 12sourceSize 13{740,105} 14aoao1.png 1617 24frame 18{ {360,109},{68,97}} 19offset 20{3,-4} 21sourceSize 22{74,105} 23aoao10.png 2526 33frame 27{ {220,109},{68,99}} 28offset 29{3,-3} 30sourceSize 31{74,105} 32aoao2.png 3435 42frame 36{ {290,109},{68,97}} 37offset 38{3,-4} 39sourceSize 40{74,105} 41aoao3.png 4344 51frame 45{ {498,109},{66,95}} 46offset 47{3,-5} 48sourceSize 49{74,105} 50aoao4.png 5253 60frame 54{ {430,109},{66,95}} 55offset 56{3,-5} 57sourceSize 58{74,105} 59aoao5.png 6162 69frame 63{ {566,109},{64,93}} 64offset 65{3,-6} 66sourceSize 67{74,105} 68aoao6.png 7071 78frame 72{ {566,109},{64,93}} 73offset 74{3,-6} 75sourceSize 76{74,105} 77aoao7.png 7980 87frame 81{ {148,109},{70,105}} 82offset 83{-1,0} 84sourceSize 85{74,105} 86aoao8.png 8889 96frame 90{ {2,109},{72,105}} 91offset 92{-1,0} 93sourceSize 94{74,105} 95aoao9.png 9798 105frame 99{ {76,109},{70,105}} 100offset 101{-1,0} 102sourceSize 103{74,105} 104metadata 107108 119format 1091 110realTextureFileName 111aoao.png 112size 113{1024,256} 114smartupdate 115$TexturePacker:SmartUpdate:04e5a7f7e0f4e21dfa7ecb6ac7f51df1$ 116textureFileName 117aoao.png 118
将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 ListanimFrames = new List (); 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:CCLayer10 {11 public AnimateLayer()12 {13 CCDirector.sharedDirector().deviceOrientation = ccDeviceOrientation.kCCDeviceOrientationPortraitUpsideDown;//设置朝向,竖屏14 15 #region 单帧动画CCSpriteFrame16 //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 //ListanimFrames = new List (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 ////动画Animate46 //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 #endregion52 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 animFrames = new List ();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 //动画Animate75 CCAnimation animation = CCAnimation.animationWithFrames(animFrames, 0.2f);//Animation动画信息76 sprite1.runAction(CCRepeatForever.actionWithAction(CCAnimate.actionWithAnimation(animation, false)));//执行动画77 #endregion78 }79 }80 }
显示效果,同样可以得到一样的效果
本实例源码
著作权声明:本文由 原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!