Cocos2d-x 3.x制作动画的实例,就拿我这几天想做的 FlappyBird 的小鸟为例吧。


1.首先,我们先来做需要的资源

这个有三个层次(目前我知道的)

① 加载每个图片

② 把所有图片压缩到一张图片中,然后分割取出。

③ 借助于plist文件与png共同取出图片。

前两种,比较简单,而且效率不是很高,我就直接用这三者最好的,plist+png。

其实,plist一般是用在Mac上的,在Windows制作plist可以用 TexturePacker点击下载)。

非常方便的一个工具。安装完毕,打开,需要选择你的引擎,当然我们选择的是Cocos2d的:

20140928181845468.jpg

打开以后,会出现如下界面:

20140928182258962.jpg

这个工具的使用细节,我不是很懂,详细的可以问问度娘。

我只知道,点上面那个按钮,添加,你所需要压缩在PNG里的图片:

20140928182304297.jpg

这个技巧不需要我多说了吧:按住Ctrl 可以单个多选,按住Shift可以连续多选。选出图片,并把他们加入进来。

如果没有图片,拿下面的凑合一下吧:

20140928182453062.png20140928182636005.png20140928182639624.png

然后点击左上角的File按钮:

20140928182931037.jpg

然后,在下拉的菜单中,选  Public sprite sheet ,然后就选择存放 PNG和PLIST的目录:

20140928205818387.jpg

先是plist目录,然后是PNG目录,最好两个文件名是一样的。

接着,就会给你输出出来了:

20140928210026978.jpg

OK,你就可以到存放的地方看你所生成的两个文件了。


2.接下来就是Cocos2d-x中调用部分了。

把两个文件(plist和png) 复制到Resource 里面,在VS2012 中 右键点击Resource 文件夹,添加->现有项,将两者添加进来。

20140928213309968.jpg

这里,我就直接在HelloWorld界面,放小鸟飞行动画了。


在HelloWorldScene.cpp的Init函数中加入,如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ①创建缓存,将图片读取进来  
CCSpriteFrameCache * cache = CCSpriteFrameCache::sharedSpriteFrameCache();    
cache -> addSpriteFramesWithFile("hero_bird.plist");  
   
// ②创建第一帧,设置位置,加入到当前场景  
CCSprite *sp = CCSprite::createWithSpriteFrameName("bird_hero_01.png");  
sp -> setPosition(Point(visibleSize.width/3,visibleSize.height/2));  
this -> addChild( sp );  
   
// ③创建集合,存每一张图片  
Vector< SpriteFrame* > sfme = Vector< SpriteFrame* >::Vector();  
char str[20] = {0};  
for( int i = 1 ; i < 4 ; ++i )  
{  
     // ④ 获取图片名字,加入到集合中  
     sprintf(str,"bird_hero_d.png",i);  
     SpriteFrame *fname = cache -> spriteFrameByName( str );  
     sfme.pushBack( fname );  
}  
// ⑤ 创建动画,设置播放速度  
CCAnimation *animation = CCAnimation::createWithSpriteFrames( sfme , 0.1f );  
sp -> runAction ( CCRepeatForever::create(CCAnimate::create(animation )));

来解释一下:

前面①、② 无需多说,

③,这个以前用CCArray或者Array,

现在不行了,反正我是3.0和3.2都不能用Array,会在⑤createWithSpriteFrames出问题,

因为追到这个函数定义,可以发现:

1
2
3
4
5
6
7
8
Animation* Animation::createWithSpriteFrames(const Vector<SpriteFrame*>& frames, float delay/* = 0.0f*/, unsigned int loops/* = 1*/)  
{  
    Animation *animation = new Animation();  
    animation->initWithSpriteFrames(frames, delay, loops);  
    animation->autorelease();  
   
    return animation;  
}

它的第一个参数必须为:

1
const Vector<SpriteFrame*>& frames

这点就要和之前版本不同,要注意一下。


然后是 ④

这个获取图片名字,为什么是:sprintf(str,"bird_hero_d.png",i);呢?

因为d,可以保证,取i后,不够的用0补足。比如,如果是%d,当i等于1, 获取的名字是: bird_hero_1。

而d,获取名字是: bird_hero_01。


Ok,运行一下,就可以发现小鸟在飞翔啦~


PS:如何作为一个开场动画呢?

我的方法就是在上述代码后,加一句计划任务,

多长时间后的跳转:

1
this->scheduleOnce(schedule_selector(InkmooFlash::jumpToMain), 4);

这样,算好播放一帧多久,总共多少帧,就可以做成开场动画啦。