【目标】给扫雷添加信息面板
【参考】
《[cocos2d-x] --- 完美解决中文乱码》 http://blog.csdn.net/u010710758/article/details/9043769
《cocos2d-x 获取屏幕当前方向和系统语言》 http://blog.csdn.net/cen616899547/article/details/9084783
《CCDictionary 解析xml总结》 http://blog.csdn.net/jalen_yuchi/article/details/8617348
一、对目标的概述
期望的结果,是类似于MS的扫雷中的信息板,显示耗时和剩余雷数(我这里显示的剩余未探索的安全区域数)。
二、显示中文
要显示信息,首先要解决的就是中文显示问题。在cocos2D-x中,中文字符串是不能直接显示的,例如下面的代码:
CCLabelTTF * ret = CCLabelTTF::create(“中文”, font, size);可以通过编译,但是显示出来是乱码。这是由于默认的工程中的char是ASCII编码,在传递的时候出现了问题。在WINDOWS程序中,可以通过WCHAR的_T宏来解决这个问题。不过显然这个方法在跨平台的cocos中是行不通的,要解决这个问题,有以下几个思路:
1、可以通过iconv库,不过根据网上搜索的情报(我并没有尝试),这个库貌似只有WIN32平台上可以用,在android上还是要另想办法。
2、直接把文字保存为纹理,通过显示纹理来显示,和范例中的使用fps_images来显示帧数是一个道理。
3、将文字信息保存在XML中,通过读取XML来获取字符串,这个机制和android是类似的。
我这里最终决定采用的是第三种,第二种在本节也会涉及到。
1、获取当前系统语言
要实现类似于android的机制,当然要使得语言能够随着系统语言的切换而进行自适应,这点听上去很厉害,但实际上用XML来实现非常容易——只需要根据语言的不同来确定解析文件的路径即可,例如默认的英文就是 values 下的 strings.xml,而中文的 strings.xml则放在 values-zh-rCN下。
在cocos中,获取系统的语言已经有了简单的办法:
ccLanguageType curLocale = CCApplication::sharedApplication()->getCurrentLanguage();
typedef enum LanguageType { kLanguageEnglish = 0, kLanguageChinese, kLanguageFrench, kLanguageItalian, kLanguageGerman, kLanguageSpanish, kLanguageRussian, kLanguageKorean } ccLanguageType;可以看到实际上支持的语种并不多(而且居然没有日语)。
2、根据系统语言来确定资源文件目录
通过switch-case很容易实现这个功能点,另外还有一种方式是学习HelloCpp中的根据分辨率来指定资源文件夹的方式:
CCFileUtils::sharedFileUtils()->setResourceDirectory(largeResource.directory);
两种各有好处,不过我觉得资源文件与字符串文件分开放置处理会更好。所以字符串仍然使用switch来确定。
3、利用 CCDictionary 从 strings.xml中读取字符串
利用CCDictionary可以简单的解析XML文件,不过对于XML文件的格式有要求。这里可以参考 http://blog.csdn.net/jalen_yuchi/article/details/8617348, 写的非常详细。对于我这里而言,只需要这样组织 strings.xml:<?xml version="1.0" encoding="utf-8"?> <dict> <key>app_name</key><string>MineSweeping</string> <key>hello</key><string>Hello World</string> </dict>
三、计划任务
在cocos中启动计划任务可以使用 schedule 宏,标准格式如下:
schedule(schedule_selector(InfoPanel::refreshTimer), 1.0f);这样就启动了一个update计时器,从调用schedule开始,每隔1.0f执行一次 refreshTimer,(第一次执行是在调用schedule后1.0f秒)。直到调用对应的 unschedule 方法
unschedule(schedule_selector(InfoPanel::refreshTimer));这里 schedule_selector 中传递的函数指针格式如下:
void refreshTimer(float dt);其中,dt是距离上一次调用的时间间隔,如果是第一次调用,则是启动到调用之间的间隔,一般都在1.0f左右,略有延时,即为 1.0008s 左右。
通过这个计划任务,可以很容易的实现扫雷中的计时器,比较简单,不贴代码了。