博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Learning Cocos2d-x for XNA(7)——让Sprite动起来
阅读量:5099 次
发布时间:2019-06-13

本文共 21488 字,大约阅读时间需要 71 分钟。

本讲将详细介绍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: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             List
animFrames = 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完整代码

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             List
animFrames = 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

 修改代码后

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

将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
animFrames = 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完整代码

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             //List
animFrames = 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 }

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

 本实例源码

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

转载于:https://www.cnblogs.com/suguoqiang/archive/2013/02/04/2891677.html

你可能感兴趣的文章
设计模式之装饰者模式
查看>>
一道不知道哪里来的容斥题
查看>>
Blender Python UV 学习
查看>>
window添加右键菜单
查看>>
入手腾龙SP AF90mm MACRO
查看>>
python学习4 常用内置模块
查看>>
Window7上搭建symfony开发环境(PEAR)
查看>>
ResolveUrl的用法
查看>>
Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3
查看>>
第23月第24天 git命令 .git-credentials git rm --cached git stash clear
查看>>
java SE :标准输入/输出
查看>>
一些方便系统诊断的bash函数
查看>>
【转载】基于vw等viewport视区相对单位的响应式排版和布局
查看>>
<转>关于MFC的多线程类 CSemaphore,CMutex,CCriticalSection,CEvent
查看>>
jquery中ajax返回值无法传递到上层函数
查看>>
css3之transform-origin
查看>>
[转]JavaScript快速检测浏览器对CSS3特性的支持
查看>>
Master选举原理
查看>>
[ JAVA编程 ] double类型计算精度丢失问题及解决方法
查看>>
小别离
查看>>