首页 > 代码库 > Cocos2d-x 系列六之数据操作
Cocos2d-x 系列六之数据操作
一、定时器
在cocos2d-x中, 类似定时器的操作,不需要额外的写Timer,实际上,在Node元素中,已经添加了定时执行的功能;
先来看看在Node中的定义
// ... bool Node::isScheduled(SEL_SCHEDULE selector) { return _scheduler->isScheduled(selector, this); } void Node::scheduleUpdate() { scheduleUpdateWithPriority(0); } void Node::scheduleUpdateWithPriority(int priority) { _scheduler->scheduleUpdate(this, priority, !_running); } // ...
下面是一个移动LabelTTF的例子
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_NS_CC; class HelloWorld : public cocos2d::Layer { private: cocos2d::LabelTTF *label; public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(HelloWorld); virtual void update(float dt); // 1>>update方法,在此方法中做定时执行需要进行的操作 void timerHandler(float dt); // 2>>自定义时间间隔执行该方法 }; #endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp
#include "HelloWorldScene.h" #include <iostream> USING_NS_CC; using namespace cocos2d; Scene* HelloWorld::createScene() { auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { // 1. super init first if (!Layer::init()) { return false; } label = LabelTTF::create("Move", "Courier", 30); addChild(label); // scheduleUpdate(); 1>>启用该方法后,会在程序运行每一帧执行update方法,需要指定update方法进行实现; schedule(schedule_selector(HelloWorld::timerHandler), 1); // 2>>每隔1s执行一次timerHandler方法 @1 return true; } void HelloWorld::update(float dt) { label->setPosition(label->getPosition() + Point(1, 1)); if (label->getPosition().x > 500) { unscheduleUpdate(); // 1>>停止循环执行update方法 } } void HelloWorld::timerHandler(float dt) { // >>2 log(">>>>>"); }
@1 下面来看schedule方法在Node中的定义,可以看到schedule方法的第一个参数是一个SEL_SCHEDULE;
void Node::schedule(SEL_SCHEDULE selector) { this->schedule(selector, 0.0f, kRepeatForever, 0.0f); } void Node::schedule(SEL_SCHEDULE selector, float interval) { this->schedule(selector, interval, kRepeatForever, 0.0f); } void Node::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay) { CCASSERT( selector, "Argument must be non-nil"); CCASSERT( interval >=0, "Argument must be positive"); _scheduler->schedule(selector, this, interval , repeat, delay, !_running); }
参看SEL_SCHEDULE的定义:
typedef void (Ref::*SEL_SCHEDULE)(float);
#define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)
由此看出它其实是一个c++函数指针,参数为float,返回值为void(参见HelloWorldScene.h中timerHandler函数的定义);
上面讲了两种定时器,一种是schedule,另一种是scheduleUpdate,第二种方法不好的地方就是无法指定时间频率,由游戏的帧频决定;
二、偏好设置
在cocos2d-x中,偏好设置的含义和android中类似;
// UserDefault::getInstance()->setStringForKey("name", "Livingstone"); std::string s = UserDefault::getInstance()->getStringForKey("name1", "Hello World"); log("name=%s", s.c_str());
在上面的代码中,先保存了一个name字符串,然后进行读取;相应的,也可以保存其它数据类型;
三、文件读写
在cocos2d-x中,文件读写其实直接使用c/c++中的文件读写操作方法,但是,在实际运用中,由于移动客户端读写文件需要相应的权限,所以读写文件就需要先指定文件的路径,我们不需要获取绝对路径,只需要获取相对路径就行,因为cocos2d-x底层已经做了相应各个平台的处理;
FileUtils * fu = FileUtils::getInstance(); // log("path = %s", fu->getWritablePath().c_str()); // FILE *f = fopen(fu->fullPathFromRelativeFile("data.txt", fu->getWritablePath()).c_str(), "w"); // fprintf(f, "Hello Livingstone"); // fclose(f); 写文件 Data d = fu->getDataFromFile(fu->fullPathFromRelativeFile("data.txt", fu->getWritablePath())); log("data = http://www.mamicode.com/%s", d.getBytes());
四、plist文件读取
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>name</key> <string>Ls</string> <key>isgirl</key> <false/> </dict> </plist>
上面是一个plist文件;
FileUtils * fu = FileUtils::getInstance();
ValueMap vm = fu->getValueMapFromFile("Info.plist"); log("%s", vm["name"].asString().c_str()); // 读取string bool bl = vm["isgirl"].asBool(); // 读取bool log("%d", bl);
如果plist文件节点为数组,还可以通过ValueVector getValueVectorFromFile("xx");读取数据;
五、xml文件读取
FileUtils * fu = FileUtils::getInstance(); auto doc = new tinyxml2::XMLDocument(); doc->Parse(fu->getStringFromFile("data.xml").c_str()); auto root = doc->RootElement(); for (auto e = root->FirstChildElement(); e; e = e->NextSiblingElement()) { std::string str; for (auto attr = e->FirstAttribute(); attr; attr = attr->Next()) { str += attr->Name(); str += ":"; str += attr->Value(); str += ","; } log("%s", str.c_str()); }
data.xml
<data> <p name="zs" age="23"/> <p name="ls" age="25"/> </data>
上面的代码输出内容为:
cocos2d: name:zs,age:23,
cocos2d: name:ls,age:25,
注:需要导入cosos2d-x库 <tinyxml2/tinyxml2.h>
六、JSON文件读取
先来看一个json : [{"name": "zs","age": 23}, {"name": "ls","age": 25}]
rapidjson::Document d; d.Parse<0>(fu->getStringFromFile("dj.json").c_str()); // 0表示默认的解析方式; log("%s", d[rapidjson::SizeType(0)]["name"].GetString());
注:需要导入cocos2d-x库 <json/document.h>