cocos2d-x 血泪史(1.5) 先从helloworld 切换到menu 吧
ok 我来更新正剧了,卧槽我记得之前貌似写过1.5 后来因为机器莫名蓝屏导致坑爹的未保存然后就伤心的专注写代码不更新博客了。。
那个上回说到哪了?哦对淡入淡出的切换到menu 界面,哦对貌似上次还写了不少东西卧槽。。
本篇的主要内容有:
1. 配置文件读取
2. 随机函数使用
3. 场景切换动画
4. 精灵列表加载
5. 使用贴图缓存
5. 菜单项的使用
6. 玩转消息中心
7. 进度条的使用
8. 祖国欣欣向荣
9. 老外水深火热
10. 天气预报
呐,这个菜单呢是根据随机数动态生成的,也就是说每次进入到菜单选择场景所呈现出来的菜单上的文字是不一样的。。。比如这样的:
还有这样的:
或者这样的:
那么这是肿么做到的呢?恩。。就是随机出来的。。
首先准备一张高清无码大图menu_items.png:
然后准备对应的*.plist 文件,(这又是个啥?)恩。。这个是spritesheet,也就是精灵表,可以使用一些工具如TexturePacker 来创建出这个plist 文件和整合后的这个大png。当然cocoStudio 里的那个AnimationEditor 也是非常好用的~
接下来只要使用这样的代码:
CCTextureCache::sharedTextureCache()->addImageAsync("menu_items.png", this, callfuncO_selector(MenuScene::resourceLoadedCallback));
就可以把文件加入到cache 里,这么做的好处是之后用到加载这个PNG 的地方就会直接从cache 里拿不会去再读写文件了,我这里使用的是异步加载为的是之后能够获取资源加载进度。
然后再这样:
CCSpriteFrameCache* spriteFrameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
spriteFrameCache->addSpriteFramesWithFile(MENU_ITEMS_FILE_NAME);
就把menu_items.plist 里定义的各种frame 加到spriteFrameCache 里了
最后这样:
auto spriteFrameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); CCSprite* sprite_menu = CCSprite::createWithSpriteFrame( spriteFrameCache->spriteFrameByName(menu_string->getCString())); CCSprite* sprite_menu_selected = CCSprite::createWithSpriteFrame( spriteFrameCache->spriteFrameByName(menu_string_selected->getCString()));
就是用sprite frame 的形式来创建sprite 了。
然后要随机这些menuitem 怎么弄呢,其实就是这些spriteframe 的名字有一定的规范,比如start_001.png, start_002.png 也就是说搞个随机数来随机那个001, 002 什么的,再拼下字符串就ok 了,那还要知道每个menuitem 有多少种,恩。。。这里就用了一配置文件来定义他们的length:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 <plist version="1.0"> 4 <dict> 5 <key>start</key> 6 <string>5</string> 7 <key>settings</key> 8 <string>6</string> 9 <key>help</key> 10 <string>6</string> 11 <key>about</key> 12 <string>5</string> 13 </dict> 14 </plist>
没错,这也是一plist 文件。用下面这些代码就能轻松获取他们的值:
1 auto fileUtil = CCFileUtils::sharedFileUtils(); 2 auto plistDic = CCDictionary::createWithContentsOfFile(MENU_CONFIG_FILE_NAME); 3 int startCount = plistDic->valueForKey(STR_MENU_START)->intValue(); 4 int settingsCount = plistDic->valueForKey(STR_MENU_SETTINGS)->intValue(); 5 int helpCount = plistDic->valueForKey(STR_MENU_HELP)->intValue(); 6 int aboutCount = plistDic->valueForKey(STR_MENU_ABOUT)->intValue();
随机函数怎么用呢?
cocos2d-x 提供了个宏叫CCRANDOM_0_1 用来随机0到1 之间的一float 值,那么我们要取start_001.png, start_002.png, start_003.png, start_004.png 中的一个就像这样就行了:
1 #define FORMAT_MENU_STRING "%s_%03d.png" 2 3 4 // ... 5 int index = CCRANDOM_0_1() * nCount + 1; 6 7 CCString* menu_string = CCString::createWithFormat( 8 FORMAT_MENU_STRING, pszType, index);
注意:使用CCRANDOM_0_1 需要预先设定seed!!不然每次随机的序列都一样谁受得了,在main 函数开始的时候加上这段话:
1 // set random seed 2 cc_timeval psv; 3 CCTime::gettimeofdayCocos2d( &psv, NULL ); // 计算时间种子 4 unsigned int tsrans = psv.tv_sec * 1000 + psv.tv_usec / 1000; // 初始化随机数 5 srand( tsrans );
哦了搞定。接下来创建出来这个menuitem 就行了:
1 auto spriteFrameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); 2 CCSprite* sprite_menu = CCSprite::createWithSpriteFrame( 3 spriteFrameCache->spriteFrameByName(menu_string->getCString())); 4 CCSprite* sprite_menu_selected = CCSprite::createWithSpriteFrame( 5 spriteFrameCache->spriteFrameByName(menu_string_selected->getCString())); 6 CCMenuItemSprite* menuItem = CCMenuItemSprite::create(sprite_menu, 7 sprite_menu_selected, NULL, this, menu_selector(MenuLayer::menuCallback));
我在这里创建了个两个class, MenuScene 和MenuLayer,第一个用来动态加载texture,第二个用来呈现那些menu items,那么从我们刚开始的那个显示logo 的hello world 怎么切换到这个menuscene 呢,还要淡入淡出什么的(终于切题了啊喂!),比如等待个3 秒钟之后切换,在helloworld 那个类里加个方法:
1 void HelloWorld::moveToMenuScene(float time) 2 { 3 this->unschedule(schedule_selector(HelloWorld::moveToMenuScene)); 4 do 5 { 6 // scene change code 7 CCDirector* pDirector = CCDirector::sharedDirector(); 8 MenuScene* menu = MenuScene::create(); 9 CC_BREAK_IF(!menu); 10 CCTransitionFade* fade = CCTransitionFade::create(0.5f, menu); 11 pDirector->replaceScene(fade); 12 13 CCLOG("Another scene~"); 14 15 16 } while (0); 17 }
是的,这里用了schedule,上面有个unschedule 的调用意思是这个schedule 只执行一次,既然有unschedule 那一定要有schedule 的地方了,在helloworld 的init 方法最后加上这句:
this->schedule(schedule_selector(HelloWorld::moveToMenuScene), 3.0f);
ok,搞定,显示logo 后3 秒钟切换到menuscene
那个。。这就结束了么,结束了吧,感觉写的越来越偷懒了呢,还有,上面说好的“玩转消息中心”和“进度条的使用”哪里去了?!那个。。。敬请期待<<cocos2d-x 血泪史(1.75) 先从helloworld 切换到menu 吧>>!!!
还有!!! 忘了说了,这么用一张这么大的图来做随机按钮貌似很坑爹,因为图比较大占资源什么的,其实可以用那个九宫格的sprite 叫做CCScale9Sprite,然后用这个加上一些CCLabelTTF 什么的就ok 了还解决了多语言需要再搞一张大图的问题,这个东西怎么用呢,网上随便搜一下就行了,比如这个:http://blog.csdn.net/toss156/article/details/7911955