可能大家会发现TestCpp项目运行起来后,在主界面的菜单里面有一个名为“ZwopTexTest”的菜单选项,点击打开后我们会看到界面中有两个小人在跳舞。我们先来了解一下ZwopTex是什么东西。
ZwopTex是一个在线制作精灵表的工具,它可以很方便的创建.plist文件。那么什么是精灵表呢?它又有什么作用?
我们在讲人物动画的那一篇文章中,实现了一个小人在屏幕中央跳舞,其原理是将一段舞蹈的连贯图片一帧一帧的播放,实现出动画的效果。这样做的话我们需要载入许多的图片,对内存的利用和效率的提高都不是可取的。那么如何来改进呢?这里就要用到精灵表了。那么精灵表又是什么呢?
包含一个以上精灵的图像就叫精灵表。精灵表是一个图像中包含一系列以网格形式存在的精灵图像。对每个精灵都可以通过他在大图像中的行和列位置进行访问。精灵表又分为简单精灵表和复杂精灵表。
简单精灵表:精灵表中的图片都具有相同维度。
复杂精灵表:精灵表中的图片可以具有不同的维度。
复杂的精灵表,可以称为打包精灵表,他是包含一系列更小子图像的图像,每一个子图像又可以是其他的精灵表或者图像。复杂的精灵表,我们就无法简单的根据行和列的位置确定每个精灵的位置了,我们通过建立一个plist控制文件,来确定他们的位置。这个控制文件可以通过Zwoptex等工具生成。Zwoptex可以把分散的图像生成精灵表和控制文件。
好了,介绍完概念后,先让我们学一下怎么使用Zwoptex这个工具吧。首先下载压缩包。点此下载
将下载后的压缩包解压,找到Zwoptex.html文件并打开,我们就可以使用这个工具了,主界面如下所示
然后选择File-->import images,导入我们需要的文件,这里我们借用TestCpp示例项目里面的图片,找到D:\cocos2d-2.0-x-2.0.4\samples\TestCpp\Resources\Images(你的存放目录可能不一样)。选择grossini_dance_01.png到grossini_dance_14.png共14张图片,导入后效果如下,图片都重叠了,没关系,下一步就要展开它们。
我么先设置图片大小,选择Modify-->Canvas Width-->512px,然后Modify-->Canvas Height-->512px。接着选择Arrange-->By Name & Height就可以了
选择File-->Export Texture,命名为“grossini.png”导出图片,然后File-->Export Coordinates导出.plist文件,同样命名为“grossini.plist”,两者名字要相同。
打开VS,新建一个项目“SpriteSheetTest”,然后把导出后的文件grossini.png和grossini.plist导入到我们的项目中,具体方法就不再说明了。
我们修改HelloWorld.h文件的代码如下
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "SimpleAudioEngine.h" using namespace cocos2d; class HelloWorld : public cocos2d::CCLayer { protected: CCSprite* sprite; public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommand to return the exactly class pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); //每隔0.5秒执行的函数 void startIn05Secs(float dt); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" using namespace cocos2d; static int spriteFrameIndex = 1;
bool HelloWorld::init() { bool bRet = false; do { ////////////////////////////////////////////////////////////////////////// // super init first ////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayer::init()); ////////////////////////////////////////////////////////////////////////// // add your codes below... ////////////////////////////////////////////////////////////////////////// // 1. Add a menu item with "X" image, which is clicked to quit the program. // Create a "close" menu item with close icon, it's an auto release object. CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); CC_BREAK_IF(! pCloseItem); // Place the menu item bottom-right conner. pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20)); // Create a menu with the "close" menu item, it's an auto release object. CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer. this->addChild(pMenu, 1); //取得屏幕大小 CCSize size = CCDirector::sharedDirector()->getWinSize(); //将.plist文件加载进缓冲区 CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("grossini.plist"); //创建精灵,取得缓冲区的“grossini_dance_01.png” //注意我们并没有导入这张图片,它是我们在制作精灵表单时使用的图片 sprite = CCSprite::createWithSpriteFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("grossini_dance_01.png")); //设置位置 sprite->setPosition(ccp( size.width/2, size.height/2)); //每隔0.5秒执行一次startIn05Secs()函数 schedule(schedule_selector(HelloWorld::startIn05Secs), 0.5f); //将精灵添加到布景中 addChild(sprite); bRet = true; } while (0); return bRet; }
void HelloWorld::startIn05Secs(float dt) { //判断是否播放到结尾,若是,则重新开始 if(++spriteFrameIndex > 14) { spriteFrameIndex = 1; } //sprintf()函数前面动画那一篇已经解释过用法和功能,这里就不再赘述 char str[32] = {0}; sprintf(str, "grossini_dance_%02d.png", spriteFrameIndex); //替换当前显示的图片,从缓冲区找到下一张图片 sprite->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str)); }
祝愿每一个奋斗在路上的人早日实现梦想!