调度器:
定时任务是通过调度器实现的。cocos2d-x推荐用调度器而不是其他方法实现定时任务。Node类都知道如何调度和取消调度事件。
有3种调度器:
取消调度器:
使用默认调度器,该调度器是使用Node的刷新事件update方法,该方法在每帧绘制之前都会被调用一次。Node类默认没有启用update事件的,所以你需要重写这个update方法。update有一个float类型的形参。
使用自定义调度器:自定义的方法必须要有一个float类型的形参。
使用单次调度器:自定义的方法必须要有一个float类型的形参。
栗子:使用调度器实现定时调用移动文本标签:
1 #ifndef __HELLOWORLD_SCENE_H__
2 #define __HELLOWORLD_SCENE_H__
3
4 #include "cocos2d.h"
5
6 class HelloWorld : public cocos2d::Layer
7 {
8 private:
9 cocos2d::LabelTTF *label;
10 public:
11 // there's no 'id' in cpp, so we recommend returning the class instance pointer
12 static cocos2d::Scene* createScene();
13
14 // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
15 virtual bool init();
16
17 // a selector callback
18 void menuCloseCallback(cocos2d::Ref* pSender);
19
20 // implement the "static create()" method manually
21 CREATE_FUNC(HelloWorld);
22
23 void update(float delta) override;
24
25 void timerHandler(float delta);
26 };
27
28 #endif // __HELLOWORLD_SCENE_H__
1 #include "HelloWorldScene.h"
2
3 USING_NS_CC;
4
5 Scene* HelloWorld::createScene()
6 {
7 // 'scene' is an autorelease object
8 auto scene = Scene::create();
9
10 // 'layer' is an autorelease object
11 auto layer = HelloWorld::create();
12
13 // add layer as a child to scene
14 scene->addChild(layer);
15
16 // return the scene
17 return scene;
18 }
19
20 // on "init" you need to initialize your instance
21 bool HelloWorld::init()
22 {
23 //////////////////////////////
24 // 1. super init first
25 if ( !Layer::init() )
26 {
27 return false;
28 }
29
30 label = LabelTTF::create("Hello, Cocos", "Courier", 30);
31
32 addChild(label);
33
34 //scheduleUpdate();
35
36 schedule(schedule_selector(HelloWorld::timerHandler), 0.2f);
37
38 return true;
39 }
40
41
42 void HelloWorld::menuCloseCallback(Ref* pSender)
43 {
44 Director::getInstance()->end();
45
46 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
47 exit(0);
48 #endif
49 }
50
51 void HelloWorld::update(float delta){
52 //log("update");
53 label->setPosition(label->getPosition()+Vec2(1,1));
54 //the following line has the same effect with the above line.
55 //label->runAction(MoveBy::create(1.0f, Point(1, 1)));
56 }
57
58 void HelloWorld::timerHandler(float delta){
59 label->setPosition(label->getPosition() + Vec2(1, 1));
60 }
首选项:
使用文件存取数据不方便用户的存取。本地数据存储有两种方法,一是UserDefault,二是SQLite数据库。
UserDefault是一个单例类,数据存到以UserDefault命名的xml文件,保存方式是一个map,即key-value的键值对。存取数据通过tinyxml2。
首选项的读取,我觉得类似于Android的SharedPreferences。
1 // on "init" you need to initialize your instance
2 bool HelloWorld::init()
3 {
4 //////////////////////////////
5 // 1. super init first
6 if ( !Layer::init() )
7 {
8 return false;
9 }
10 UserDefault::getInstance()->setStringForKey("data" , "success");
11 log("%s", UserDefault::getInstance()->getStringForKey("data", "fail").c_str());
12 return true;
13 }
文件读写:
写入目录的获取比较麻烦,各个平台不同,所以用C++自己的文件读写行不通。
使用cocos2d-x自己的文件读写:当前程序的文档目录
init
plist文件操作:
plist文件是苹果应用程序的配置文件,任何的配置文件都是可以用plist去写的。
plist文件是特定格式的xml 文件。
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>array</key>
6 <array>
7 <integer>0</integer>
8 <integer>1</integer>
9 <integer>2</integer>
10 </array>
11 <key>bool</key>
12 <true/>
13 <key>data</key>
14 <data>
15 </data>
16 <key>date</key>
17 <date>2015-02-16T16:47:11Z</date>
18 <key>dict</key>
19 <dict>
20 <key>age</key>
21 <string>20</string>
22 <key>name</key>
23 <string>Alice</string>
24 </dict>
25 <key>number</key>
26 <integer>123456</integer>
27 <key>string</key>
28 <string>hello world!</string>
29 </dict>
30 </plist>
1 bool HelloWorld::init()
2 {
3 //////////////////////////////
4 // 1. super init first
5 if ( !Layer::init() )
6 {
7 return false;
8 }
9
10 FileUtils *fu = FileUtils::getInstance();
11 ValueMap plist = fu->getValueMapFromFile("test.plist");
12
13 log("string = %s", (plist["string"].asString()).c_str());
14 ValueMap& dict = plist["dict"].asValueMap();
15 log("name = %s", (dict["name"].asString()).c_str());
16 log("age = %s", (dict["age"].asString()).c_str());
17 ValueVector& array = plist["array"].asValueVector();
18 for (int i = 0; i < array.size(); i++) {
19 Value& value = array[i];
20 log("%d", value.asInt());
21 }
22 return true;
23 }
调试运行:
xml文件操作:
data.xml文件内容如下:
1 <data>
2 <p name="ZhangSan" age="10"></p>
3 <p name="LiSi" age="11"></p>
4 </data>
cocos2d-x内置了API操作xml,首先需要引入头文件:
include<tinyxml2/tinyxml2.h>;
1 bool HelloWorld::init()
2 {
3 //////////////////////////////
4 // 1. super init first
5 if ( !Layer::init() )
6 {
7 return false;
8 }
9
10 auto doc = new tinyxml2::XMLDocument();//首先需要创建文档
11 doc->Parse(FileUtils::getInstance()->getStringFromFile("data.xml").c_str());//解析字符串
12 auto root = doc->RootElement();//获取到根节点,根据根节点查找到子对象
13
14 //外层循环遍历所有的子项,内存循环遍历当前子项所有的属性
15 for (auto e = root->FirstChildElement(); e!=null; e = e->NextSiblingElement()){
16 std::string str;
17 for (auto attr = e->FirstAttribute(); attr; attr = attr->Next()){
18 str += attr->Name();
19 str += ":";
20 str += attr->Value();
21 str += ",";
22 }
23 log("%s",str.c_str());
24 }
25
26 return true;
27 }
json数据操作:
cocos2d-x内置了json工具,需要引入相应的头文件:
#include <json/document.h>
1 bool HelloWorld::init()
2 {
3 //////////////////////////////
4 // 1. super init first
5 if ( !Layer::init() )
6 {
7 return false;
8 }
9
10 rapidjson::Document doc;
11 //Parse<unsigned int parseFlags>(const Ch *str):
12 //parseFlags 指解析的方式,一般用默认的解析方式,只需要传入0就好了
13 doc.Parse<0>(FileUtils::getInstance()->getStringFromFile("data.json").c_str());
14 log("%s", doc[(rapidjson::SizeType)0]["name"].GetString());
15 return true;
16 }