一、定時器
在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 = %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 -->Ls
bool bl = vm["isgirl"].asBool(); // 讀取bool -->0
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>