|
#
一切又歸零了。不解釋什么! 無(wú)所謂得,無(wú)所謂失 有任性,有責(zé)任 2016終于開(kāi)始。
本文地址:http://m.shnenglu.com/zdhsoft/archive/2014/09/03/208216.html 本文基于cocos2dx 3.2 cocos2dx 提供了一個(gè)基于xml的用戶(hù)數(shù)據(jù)存貯類(lèi),給基于cocos2dx開(kāi)發(fā)的用戶(hù)數(shù)據(jù)存貯,這個(gè)類(lèi)名就是UserDefault,在cocos2dx 2.x中是CCUserDefault。我的程序用的就是這個(gè),但是最近老出錯(cuò),于是分析源代碼,發(fā)現(xiàn)了一個(gè)讓我震驚的東西。經(jīng)過(guò)分析,發(fā)現(xiàn)用UserDefault每讀寫(xiě)一次數(shù)據(jù),都會(huì)創(chuàng)建一個(gè)tinyxml對(duì)象,然后讀取xml內(nèi)容。如果是寫(xiě)數(shù)據(jù),還是寫(xiě)入xml一次。下面是對(duì)應(yīng)的代碼: 讀取key,所以各種讀取key的操作,都是類(lèi)似這樣。 double UserDefault::getDoubleForKey(const char* pKey, double defaultValue) { const char* value = nullptr; tinyxml2::XMLElement* rootNode; tinyxml2::XMLDocument* doc; tinyxml2::XMLElement* node; node = getXMLNodeForKey(pKey, &rootNode, &doc); // find the node if (node && node->FirstChild()) { value = (const char*)(node->FirstChild()->Value()); }
double ret = defaultValue;
if (value) { ret = utils::atof(value); }
if (doc) delete doc;
return ret; } 關(guān)于getXMLNodeForKey的實(shí)現(xiàn) /** * define the functions here because we don't want to * export xmlNodePtr and other types in "CCUserDefault.h" */
static tinyxml2::XMLElement* getXMLNodeForKey(const char* pKey, tinyxml2::XMLElement** rootNode, tinyxml2::XMLDocument **doc) { tinyxml2::XMLElement* curNode = nullptr;
// check the key value if (! pKey) { return nullptr; }
do { tinyxml2::XMLDocument* xmlDoc = new tinyxml2::XMLDocument(); *doc = xmlDoc;
std::string xmlBuffer = FileUtils::getInstance()->getStringFromFile(UserDefault::getInstance()->getXMLFilePath());
if (xmlBuffer.empty()) { CCLOG("can not read xml file"); break; } xmlDoc->Parse(xmlBuffer.c_str(), xmlBuffer.size());
// get root node *rootNode = xmlDoc->RootElement(); if (nullptr == *rootNode) { CCLOG("read root node error"); break; } // find the node curNode = (*rootNode)->FirstChildElement(); while (nullptr != curNode) { const char* nodeName = curNode->Value(); if (!strcmp(nodeName, pKey)) { break; }
curNode = curNode->NextSiblingElement(); } } while (0);
return curNode; } 關(guān)于setValueForKey的實(shí)現(xiàn) static void setValueForKey(const char* pKey, const char* pValue) { tinyxml2::XMLElement* rootNode; tinyxml2::XMLDocument* doc; tinyxml2::XMLElement* node; // check the params if (! pKey || ! pValue) { return; } // find the node node = getXMLNodeForKey(pKey, &rootNode, &doc); // if node exist, change the content if (node) { if (node->FirstChild()) { node->FirstChild()->SetValue(pValue); } else { tinyxml2::XMLText* content = doc->NewText(pValue); node->LinkEndChild(content); } } else { if (rootNode) { tinyxml2::XMLElement* tmpNode = doc->NewElement(pKey);//new tinyxml2::XMLElement(pKey); rootNode->LinkEndChild(tmpNode); tinyxml2::XMLText* content = doc->NewText(pValue);//new tinyxml2::XMLText(pValue); tmpNode->LinkEndChild(content); } }
// save file and free doc if (doc) { doc->SaveFile(UserDefault::getInstance()->getXMLFilePath().c_str()); delete doc; } } 它的flush方法也有驚人的發(fā)現(xiàn): void UserDefault::flush() { } 它是一個(gè)空函數(shù),也就是說(shuō),你在寫(xiě)入數(shù)據(jù)的時(shí)候,會(huì)以為最后會(huì)通過(guò)flush才會(huì)寫(xiě)入數(shù)據(jù),沒(méi)想全錯(cuò)了! 如果你用它存貯比較多的字段時(shí),你就會(huì)現(xiàn),你悲劇了。 幸好發(fā)現(xiàn)及時(shí),這里不建議大家使用UserDefault做為你的數(shù)據(jù)存貯。 可以可以用自定義的方式文件讀寫(xiě) 如可以通過(guò)標(biāo)準(zhǔn)的C讀寫(xiě) fopen,fwrite等或iostream也都可以,重點(diǎn)是讀寫(xiě)的文件路徑,會(huì)有所不同,下面是得到文件路徑的例子 std::string strFullFileName = FileUtils::getInstance()->getWritablePath() + DATA_FILE_NAME;
最后:不要求寫(xiě)太高質(zhì)量的代碼,但也不要寫(xiě)的太低質(zhì)量了
本文地址:http://m.shnenglu.com/zdhsoft/archive/2014/08/23/208104.html 經(jīng)過(guò)幾天的填坑,終于將現(xiàn)有的項(xiàng)目由cocos2dx 2.2.2移到cocos2dx 3.2,差點(diǎn)放棄3.2了,但在最后一刻,又把坑填平了。 cocos2dx 2.x到3.x是一個(gè)巨大的變化,可以算是完全不同。以前的類(lèi)名,全是CC開(kāi)頭的,現(xiàn)在全部去掉了。很多enum都改用enum class了 所以,你知道2.x,對(duì)不起,你比小白學(xué)習(xí)3.x更難。你用2.x的做法用在3.x,那就全是坑了... 言歸正傳, 2.x的時(shí)候,按鈕設(shè)置為Disabled的時(shí)候,是看不見(jiàn)。3.x的是沒(méi)有禁用狀態(tài)的,但是不會(huì)響應(yīng)touch事件。 在cocostudio UI編輯的時(shí)候,按鈕是三種狀態(tài)的(有三個(gè)不同狀態(tài)的圖片),但沒(méi)有相應(yīng)改變狀態(tài)的函數(shù) 于是,就分析源碼,發(fā)現(xiàn)它是在onPressStateChangedToDisabled();更改為禁用狀態(tài)的圖片。再找,是于 在其基類(lèi)的ui:Widget的setBright和setHighlight有調(diào)用這個(gè)onPressStateChangedToDisabled,但是setEnabled僅僅是改為了一個(gè)成員變化, 所以你在這里設(shè)置disabled,就不會(huì)有任何效果。除了上面兩個(gè)函數(shù)之后,還有一個(gè)函數(shù)setBrightStyle是設(shè)置按鈕是普通狀態(tài)還是高亮狀態(tài) 下面是BrightStyle的定義 enum class BrightStyle { NONE = -1, NORMAL, HIGHLIGHT }; 下面是一個(gè)包裝的禁用啟用的函數(shù) //設(shè)置按鈕禁用啟用狀態(tài) inline void SetButtonEnabled(ui::Button * paramButton, bool paramEnabled) { if (isNULL(paramButton)) return; if (paramEnabled) { paramButton->setBright(true); paramButton->setEnabled(true); paramButton->setTouchEnabled(true); } else { paramButton->setBright(false); paramButton->setEnabled(false); paramButton->setTouchEnabled(false); } }
結(jié)果是:大家不要采用3.x系列的cocos2dx,還是用2.2.x吧 原因如下: 1、坑非常多,多的讓你放棄 2、兼容性非常不好,如果你是2.x的工程,還是用2.x的吧 3、資料非常少,開(kāi)發(fā)方提供了3.x版本,但是3.x的版本各項(xiàng)資料都非常欠缺!論壇上各種3.x的問(wèn)題貼子,很多都沒(méi)人回答。 4、3.x做了很多無(wú)所謂的精減,結(jié)果是,你用到這些他們精減的庫(kù)時(shí),你只有去哭了。(你的開(kāi)發(fā)環(huán)境不可能和他們的一樣,他們沒(méi)問(wèn)題,你的一定會(huì)有問(wèn)題) 5、千萬(wàn)不要拿來(lái)3.x做商業(yè)化的程序,會(huì)大大增加你的開(kāi)發(fā)周期和成本。
本文地址: http://m.shnenglu.com/zdhsoft/archive/2014/08/04/207906.html今天,有空翻了一下<C++Primer plus(第六版)>,看到里面有介紹新的for循環(huán)和初始化列表,但是我實(shí)現(xiàn)的動(dòng)態(tài)數(shù)組XDynamicArray不支持這些新特性,沒(méi)辦法,只好進(jìn)行改造了。 首先是for循環(huán),如下面的樣式 for(auto e:stList) { cout<<e<<endl; } 是于就各種google,和查找C++11的array的源代碼,總結(jié):就是提供一個(gè)標(biāo)準(zhǔn)的iterator和begin,end這兩個(gè)方法,就可以了。 是于定義了一個(gè)iterator //一個(gè)數(shù)組的Array的Iterator類(lèi) /* 這里提供XArrayIterator這個(gè)類(lèi),目的是使得這里支持C++11的for循環(huán) */ template<class Array> class XArrayIterator { public: typedef typename Array::ElementType & reference; typedef typename Array::ElementType * pointer;
XArrayIterator() :m_Index(ARRAY_INVALID_INDEX), m_Array(nullptr) {}
XArrayIterator(Array * paramArray, XInt paramIndex) :m_Index(paramIndex), m_Array(paramArray) {}
XArrayIterator(Array & paramArray, XInt paramIndex) :m_Index(paramIndex), m_Array(¶mArray) {}
XArrayIterator(const XArrayIterator<Array> & paramR) :m_Index(paramR.m_Index), m_Array(paramR.m_Array) {}
XArrayIterator & operator = (const XArrayIterator<Array> & paramR) { if (this != ¶mR) { m_Index = paramR.m_Index; m_Array = paramR.m_Array; } return *this; }
XArrayIterator & operator = (Array * paramArray) { m_Array = paramArray; if (isNotNULL(m_Array)) { m_Array = m_Array->getFirstIndex(); } else { m_Index = ARRAY_INVALID_INDEX; } return *this; }
bool operator == (const XArrayIterator<Array> & paramR) { return m_Index == paramR.m_Index && m_Array == paramR.m_Array; }
bool operator != (const XArrayIterator<Array> & paramR) { return m_Index != paramR.m_Index || m_Array != paramR.m_Array; } reference operator*() { return (*m_Array)[m_Index]; } const reference operator*() const { return (*m_Array)[m_Index]; }
pointer operator->() { return &(*m_Array[m_Index]); }
const pointer operator->() const { return &(*m_Array[m_Index]); }
XArrayIterator & operator ++() { if (m_Index != ARRAY_INVALID_INDEX && isNotNULL(m_Array)) { m_Index++; if (m_Index >= m_Array->getLength()) m_Index = ARRAY_INVALID_INDEX; } return *this; }
XArrayIterator operator ++(int) { XArrayIterator stRet = *this; if (m_Index != ARRAY_INVALID_INDEX && isNotNULL(m_Array)) { m_Index++; if (m_Index >= m_Array->getLength()) m_Index = ARRAY_INVALID_INDEX; } return stRet; }
XArrayIterator & operator --() { if (m_Index != ARRAY_INVALID_INDEX && isNotNULL(m_Array)) { m_Index--; if (m_Index < 0) m_Index = ARRAY_INVALID_INDEX; } return *this; }
XArrayIterator operator --(int) { XArrayIterator stRet = *this; if (m_Index != ARRAY_INVALID_INDEX && isNotNULL(m_Array)) { m_Index--; if (m_Index < 0) m_Index = ARRAY_INVALID_INDEX; } return stRet; }
XArrayIterator & operator +=(XInt paramOffset) { if (m_Index != ARRAY_INVALID_INDEX && isNotNULL(m_Array)) { m_Index += paramOffset; if (!(m_Index >= 0 && m_Index < m_Array->getLength())) { m_Index = ARRAY_INVALID_INDEX; } } return *this; }
XArrayIterator operator + (XInt paramOffset) const { XArrayIterator stRet = *this; stRet += paramOffset; return stRet; }
XArrayIterator & operator -=(XInt paramOffset) { return operator += (-paramOffset); }
XArrayIterator operator - (XInt paramOffset) const { XArrayIterator stRet = *this; stRet -= paramOffset; return stRet; } private: XInt m_Index; Array * m_Array; }; 然后在XDynamicArray兩個(gè)方法 typedef XArrayIterator<XDynamicArray<T> > iterator /*這里定義begin和end主要有兩個(gè)目的 目的1:使它可以像標(biāo)準(zhǔn)STD容器那樣遍歷 目的2:使它可以支持C++11的for循環(huán) 例子: XDynamicArray<int> st; for(auto x:st) { cout<<x<<endl; } */ iterator begin() { iterator stRet(this, this->getFirstIndex()); return stRet; }
iterator end() { iterator stRet(this, ARRAY_INVALID_INDEX); return stRet; } 這樣就可以了,測(cè)試通過(guò)。你們也可以試試。 C++11的另一個(gè)特性,就是新初始化列表,如下面例子 vector st {1,2,3,4,5}; 看起來(lái)有點(diǎn)意思,于是又google一下,翻閱了各位大神的貼子,最終找到,然后我就實(shí)現(xiàn)了。這部分需要使用C++11的initializer_list模板類(lèi),具體使用代碼如下。 //這個(gè)構(gòu)造函數(shù)的定義,是為了實(shí)現(xiàn)C++11的初始化列表,如下例子 /* XDynamicArray<int> st {1,2,3,4,5}; 或 XDynamicArray<int> st = {1,2,3,4,5}; */ XDynamicArray(std::initializer_list<T> paramList) : m_Length(0), m_Capacity(0), m_Data(NULL) { this->ensureCapacity((XInt)paramList.size()); for (auto e : paramList) { Append(e); } } 使用initializer_list需要頭文件:#include <initializer_list> 上述代碼,已經(jīng)放到我的開(kāi)放庫(kù)中了,大家可以自行下載。 我的開(kāi)放代碼
本文地址: http://m.shnenglu.com/zdhsoft/archive/2014/08/01/207880.html現(xiàn)在C++智能指針有無(wú)數(shù)個(gè)實(shí)現(xiàn)了,多一個(gè)也無(wú)所謂。哈。 這個(gè)智能指針是專(zhuān)門(mén)為cocos2dx 2.2.x定制的。主要是為了方便使用,同時(shí)又要遵循現(xiàn)有的cocos2dx的內(nèi)存管理。特實(shí)現(xiàn)這樣一個(gè)智能指針。在使用的時(shí)候不需要考慮retain或release操作,也不需要new或delete操作! 下面是實(shí)現(xiàn)代碼 //在很多時(shí)候,類(lèi)的成員是CCObject的子對(duì)象,為了保證對(duì)其正常使用,又要遵循cocos2dx的內(nèi)存管理,特實(shí)現(xiàn)了這樣的一個(gè)智能指針,方便使用。 #ifndef _X_COCOS_PTR_H_ #define _X_COCOS_PTR_H_ namespace zdh { template<class T> class XCocosPtr { public: XCocosPtr() :m_Object(nullptr) {}
XCocosPtr(T * paramObject) :m_Object(paramObject) { if (m_Object != nullptr) { m_Object->retain(); } }
XCocosPtr(const XCocosPtr & paramPtr) :m_Object(paramPtr.m_Object) { if (m_Object != nullptr) { m_Object->retain(); } }
~XCocosPtr() { ptr_release(); } //重載賦值運(yùn)算符 XCocosPtr & operator = (T * paramObject) { set(paramObject); return *this; }
XCocosPtr & operator = (XCocosPtr & paramObject) { set(paramObject.m_Object); return *this; } //重載比較運(yùn)算符 bool operator == (T * paramObject) const { return m_Object == paramObject; }
bool operator != (T * paramObject) const { return m_Object != paramObject; } //重載*運(yùn)算符 T & operator*() { return *m_Object; }
const T & operator*() const { return *m_Object; } //重載->運(yùn)算符,使其可以像指針那樣使用 T * operator ->() { return m_Object; }
const T * operator ->() const { return m_Object; } //判斷對(duì)象是否為空 bool is_null() const { return m_Object == nullptr; } //判斷對(duì)象是否為不空 bool is_not_null() const { return m_Object != nullptr; } //創(chuàng)建對(duì)象 這里會(huì)使用調(diào)用對(duì)象的create來(lái)創(chuàng)建對(duì)象 T * create() { T * pNewObject = T::create(); set(pNewObject); return pNewObject; } //設(shè)置對(duì)象 void set(T * paramObject) { if (m_Object != paramObject) { T * p = m_Object; m_Object = paramObject; if (m_Object != nullptr) { m_Object->retain(); } if (isNotNULL(p)) { p->release(); } } } //取對(duì)象 T * get() { return m_Object; } //這里沒(méi)有使用release這個(gè)名稱(chēng),是為了防止和object的release混淆 void ptr_release() { if (m_Object != nullptr) { m_Object->release(); m_Object = nullptr; } } private: T * m_Object; }; } #endif 例子 //類(lèi)的數(shù)據(jù)成員定義:
XCocosPtr<CCSprite> m_Sprite; //在init中
m_Sprite = CCSprite::create("  "); //或
m_Sprite.create()
本文地址: http://m.shnenglu.com/zdhsoft/archive/2014/07/25/207805.html用CCLabelTTF顯示的數(shù)字不好看,于是就想到用圖片來(lái)代理。目前網(wǎng)上的實(shí)現(xiàn)都是把每個(gè)數(shù)字做一個(gè)CCSprite組合的方式。但是我想,動(dòng)態(tài)生成紋理的方式。沒(méi)有就只好自己手動(dòng)寫(xiě)一個(gè)。 頭文件 #ifndef _X_NUMBER_H_ #define _X_NUMBER_H_ #include <cocos2d.h> #include <xtype.h> namespace cocos2d { //基于圖片顯示的數(shù)字 /* 這個(gè)類(lèi)不是用一個(gè)一個(gè)數(shù)字拼起來(lái),而是渲染成一個(gè)獨(dú)立的紋理 zdh::XDDWord是一個(gè)64位無(wú)符號(hào)整數(shù) */ class CCPictureNumber : public CCSprite { public: typedef CCSprite Inherited; public: CCPictureNumber(); ~CCPictureNumber(); virtual bool init(void); int BuildNumber(zdh::XDDWord paramNumber, const char * paramNumberResName); int BuildNumber(zdh::XDDWord paramNumber, CCTexture2D * paramTexture); int BuildNumber(zdh::XDDWord paramNumber); CREATE_FUNC(CCPictureNumber);
void setNumberTexture(CCTexture2D * paramTexture); void setNumberTexture(const char * paramNumberResName); CCTexture2D * getNumberTexture();
zdh::XDDWord getNumber() const; void setNumber(zdh::XDDWord paramNumber); int Build(); private: CCTexture2D * m_NumberTexture; zdh::XDDWord m_Number; }; } #endif 源文件 #include "xpicture_number.h" #include <xstring.h> namespace cocos2d { //-------------------------------------------------------------------------------------- //從指定資源名稱(chēng)構(gòu)建 int CCPictureNumber::BuildNumber(zdh::XDDWord paramNumber, const char * paramNumberResName) { this->setNumber(paramNumber); this->setNumberTexture(CCTextureCache::sharedTextureCache()->addImage(paramNumberResName)); return this->Build(); }
//-------------------------------------------------------------------------------------- //從指定紋理構(gòu)建 int CCPictureNumber::BuildNumber(zdh::XDDWord paramNumber, CCTexture2D * paramTexture) { this->setNumber(paramNumber); this->setNumberTexture(paramTexture); return this->Build(); } //-------------------------------------------------------------------------------------- int CCPictureNumber::BuildNumber(zdh::XDDWord paramNumber) { this->setNumber(paramNumber); return this->Build(); }
//-------------------------------------------------------------------------------------- bool CCPictureNumber::init(void) { if (!Inherited::init()) return false; return true; } //-------------------------------------------------------------------------------------- CCPictureNumber::CCPictureNumber() { m_NumberTexture = nullptr; m_Number = 0; } //-------------------------------------------------------------------------------------- CCPictureNumber::~CCPictureNumber() { if (zdh::isNotNULL(m_NumberTexture)) { m_NumberTexture->release(); } } //-------------------------------------------------------------------------------------- void CCPictureNumber::setNumberTexture(CCTexture2D * paramTexture) { if (m_NumberTexture == paramTexture) return; if (zdh::isNotNULL(m_NumberTexture)) { m_NumberTexture->release(); } m_NumberTexture = paramTexture; if (zdh::isNotNULL(m_NumberTexture)) { m_NumberTexture->retain(); } } //-------------------------------------------------------------------------------------- void CCPictureNumber::setNumberTexture(const char * paramNumberResName) { this->setNumberTexture(CCTextureCache::sharedTextureCache()->addImage(paramNumberResName)); }
//-------------------------------------------------------------------------------------- CCTexture2D * CCPictureNumber::getNumberTexture() { return m_NumberTexture; } //-------------------------------------------------------------------------------------- int CCPictureNumber::Build() { if (zdh::isNULL(m_NumberTexture)) return zdh::ERR_FAIL;
zdh::XAnsiString strNumber(m_Number); //將整數(shù)轉(zhuǎn)換為字符串 int iNumCount = strNumber.getLength(); //取得字符個(gè)數(shù) CCSize stSize = m_NumberTexture->getContentSize(); //取得紋理大小,要求紋理中每個(gè)數(shù)字都是等寬等高,并依照0123456789排列 int iNumWidth = (int)stSize.width / 10; //紋理中每個(gè)數(shù)字的寬度 int iNumHeight = (int)stSize.height; //紋理中每個(gè)數(shù)字的高度
CCRenderTexture * pRT = CCRenderTexture::create(iNumWidth * iNumCount, iNumHeight); //創(chuàng)建渲染紋理對(duì)象,并數(shù)字確定寬度 CCSprite * pSprite = CCSprite::create(); //創(chuàng)建精靈對(duì)象,用于繪制數(shù)字 pSprite->setAnchorPoint(0, 0); pSprite->setTexture(m_NumberTexture); CCRect stRect; pRT->begin(); for (int i = 0; i < iNumCount; i++) { int iNumber = strNumber[i] - '0'; //設(shè)置要顯示數(shù)字的紋理區(qū)域,這個(gè)區(qū)域是指參數(shù)中paramTexture中區(qū)域 stRect.setRect(iNumber * iNumWidth, 0, iNumWidth, iNumHeight); pSprite->setTextureRect(stRect, false, stRect.size); pSprite->setPosition(i * iNumWidth, 0); //計(jì)算顯示的偏移位置 pSprite->visit(); //渲染到pRT中 } pRT->end(); //取得生成的紋理 this->setTexture(pRT->getSprite()->getTexture()); //設(shè)置顯示的內(nèi)容 stRect.setRect(0, 0, iNumWidth * iNumCount, iNumHeight); this->setTextureRect(stRect, false, stRect.size); //默認(rèn)的情況下,通過(guò)CCRenderTexture得到的紋理是倒立的,這里需要做一下翻轉(zhuǎn) this->setFlipY(true); //釋放資源 delete pSprite; delete pRT; return zdh::ERR_OK; } //-------------------------------------------------------------------------------------- zdh::XDDWord CCPictureNumber::getNumber() const { return m_Number; } //-------------------------------------------------------------------------------------- void CCPictureNumber::setNumber(zdh::XDDWord paramNumber) { m_Number = paramNumber; }
} 數(shù)字圖片文件  使用例子 CCPictureNumber * pNum = CCPictureNumber::create(); pNum->BuildNumber(1234567, "ui_play_num05.png"); pNum->setPosition(200, 200); pNum->setAnchorPoint(0, 0);
this->addChild(pNum, 100); //
本文地址: http://m.shnenglu.com/zdhsoft/archive/2014/07/23/207760.html使用cocostudio可以裝載編輯好的UI,但是過(guò)于復(fù)雜。特別是在加截UI后,發(fā)現(xiàn)觸屏事件有些問(wèn)題。如果直接使用程序?qū)懰兰虞dUI又過(guò)于麻煩。花點(diǎn)時(shí)間,增加了一個(gè)基于ini的UI配置類(lèi),目前只實(shí)現(xiàn)了CCSprite和plist的加載。其它的可以后面慢慢加 頭文件 #ifndef _X_UI_H_ #define _X_UI_H_ #include <cocos2d.h> namespace zdh { USING_NS_CC; void CreateByXUI(CCNode * paramParent, const char * paramFileName); } #endif 源文件 #include "xui.h" #include "xini.h" #include "xlog.h"
namespace zdh { namespace xui { //-------------------------------------------------------------------------------------- int GetIntValue(XIniText::TSection * paramSection, const char * paramKeyName) { auto pV = paramSection->getEntry(paramKeyName); if (isNULL(pV)) return 0; else return pV->getValue().getField().ToIntDef(0); } //-------------------------------------------------------------------------------------- int GetDoubleValue(XIniText::TSection * paramSection, const char * paramKeyName) { auto pV = paramSection->getEntry(paramKeyName); if (isNULL(pV)) return 0; else return pV->getValue().getField().ToIntDef(0); } //-------------------------------------------------------------------------------------- const XAnsiString & GetStringValue(XIniText::TSection * paramSection, const char * paramKeyName) { static const XAnsiString strEmpty; auto pV = paramSection->getEntry(paramKeyName); if (isNULL(pV)) return strEmpty; else return pV->getValue().getField(); } };
//-------------------------------------------------------------------------------------- void CreateSpriteByXUI(CCNode * paramParent, XIniText::TSection * paramSpriteSection) { XInt ix = xui::GetIntValue(paramSpriteSection, "x"); XInt iy = xui::GetIntValue(paramSpriteSection, "y"); XInt izOrder = xui::GetIntValue(paramSpriteSection, "zOrder"); const XAnsiString & pImageName = xui::GetStringValue(paramSpriteSection, "image"); XInt iTag = xui::GetIntValue(paramSpriteSection, "tag"); CCSprite * pSprite = NULL; if (pImageName[0] == ':') //如果是從Cache中讀取 { pSprite = CCSprite::createWithSpriteFrameName(pImageName.c_str()+1); } else { pSprite = CCSprite::create(pImageName.c_str()); } pSprite->setPosition(ix, iy); pSprite->setAnchorPoint(0, 0); pSprite->setTag(iTag); pSprite->setZOrder(izOrder); paramParent->addChild(pSprite, izOrder); } void LoadSpriteFrameByPList(CCNode * /*paramParent*/, XIniText::TSection * paramSection) { const XAnsiString & pPListName = xui::GetStringValue(paramSection, "filename"); CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(pPListName.c_str()); }
//-------------------------------------------------------------------------------------- void CreateByXUI(CCNode * paramParent, const char * paramFileName) { std::string strFullFileName = CCFileUtils::sharedFileUtils()->fullPathForFilename(paramFileName); unsigned long dwGetSize = 0; const unsigned char * pData = CCFileUtils::sharedFileUtils()->getFileData(strFullFileName.c_str(), "rb", &dwGetSize); ZDH_INFO("Load XUI:%s size=%u", paramFileName, dwGetSize); if (dwGetSize == 0) { if (isNotNULL(pData)) delete[] pData; return; }
std::string strData((const char *)pData, dwGetSize); std::stringstream ss(strData); XIniText stIni; if (!stIni.Load(ss)) { ZDH_INFO("Load XUI Fail, %s", paramFileName); return; } for (int s = 0; s < stIni.getSectionCount(); s++) { auto pSection = stIni.getSection(s); auto pType = pSection->getEntry("type"); if (isNULL(pType)) { ZDH_INFO("Section=[%s] not exist key:\"type\"", pSection->getSectionName().c_str()); continue; } const XAnsiString & paramTypeValue = pType->getValue().getField(); if (paramTypeValue == "CCSprite") { CreateSpriteByXUI(paramParent, pSection); } else if (paramTypeValue == "plist") { LoadSpriteFrameByPList(paramParent, pSection); } } } } 配置文件 #支持UTF-8格式 [gk_label.png] type = CCSprite image = gk_label.png tag = 1 x = 18 y = 914 zOrder = 1
[mb_label.png] type = CCSprite image = :mb_label.png ·#冒號(hào)開(kāi)頭表示從CCSpriteFrameCache加載圖片 tag = 1 x = 348 y = 916 zOrder = 1
[score_label.png] type = CCSprite image = score_label.png tag = 1 x = 258 y = 855 zOrder = 1
[game_star.plist] #批量裝載 type = plist filename = game_star.plist 相關(guān)用到的TTextIni和XAnsiString,參考 我的開(kāi)源代碼
本文地址: http://m.shnenglu.com/zdhsoft/archive/2014/07/23/207756.html這四個(gè)是我用的主要IDE。 VS+Visual AssistX可以用無(wú)敵開(kāi)形容,太強(qiáng)大了。雖然我只用來(lái)寫(xiě)C++代碼。我個(gè)人覺(jué)得,應(yīng)該沒(méi)有什么IDE可以超過(guò)它的。沒(méi)有什么好形容它的,就是一直在用它... Eclipse也是一個(gè)非常強(qiáng)的,除了java,它還可以是C++,lua,tcl,python,ActionScript3等語(yǔ)言的IDE,現(xiàn)在cocos2dx也基于它推出cocos2dx 3.x系列的lua語(yǔ)言IDE。最新版本是luna,但是這次感覺(jué)和以前有一個(gè)最大的變化就是Menu->Help->Install new software,以前你要裝C++,那需要到CDT的頁(yè)面找插件的更新地址,其它語(yǔ)言也是類(lèi)似。但是這次它提供一個(gè)luna的插件鏈接,可以安裝各種你想要的eclipse插件,不用再一個(gè)一個(gè)找了。  當(dāng)然,一些不是eclipse一起開(kāi)發(fā)的,就還是要用老方法了。在eclipse這個(gè)工具,又衍生出FlashBuilder和ADT這兩個(gè)目前比較常見(jiàn)的開(kāi)發(fā)工具,一個(gè)用于開(kāi)發(fā)Flash,一個(gè)用于開(kāi)發(fā)Android。雖然它很NB,但是我也只是拿它打打醬油。另然,eclipse的工程文件,是讓我非常無(wú)語(yǔ)的地方,比起vs等IDE,復(fù)雜多了。它的重構(gòu)功能,還不夠,這是兩點(diǎn)是我拿它打醬油的原因。 C++Builder是我曾經(jīng)用過(guò)的編輯器,它曾經(jīng)是非常牛的。用它開(kāi)發(fā)數(shù)據(jù)庫(kù)和windows應(yīng)用,一個(gè)字,就是快。兼顧速度和可視開(kāi)發(fā)以及C++,雖然比它的本尊delphi差些,也比那個(gè)時(shí)候的vc強(qiáng)很多,易用性不比vb差。C++Builder6最后一個(gè)值得懷念的,后面borland把它的根本開(kāi)發(fā)工具賣(mài)了。最近最新的RAD Studio XE6也發(fā)布了,可以可視化開(kāi)發(fā)Android和windows以及iOS應(yīng)用,可惜bug太多,當(dāng)玩具可以,不怕死的,可以拿它去開(kāi)發(fā)商業(yè)軟件。如果你沒(méi)買(mǎi)正版,它們的代理會(huì)來(lái)找你麻煩。還有它的安裝文件巨大,你的C盤(pán)沒(méi)20G,就不要去試了。borland為什么會(huì)死,就是自己作死的。還有不得不提一下Turbo C 2.0,這是我用過(guò)最好的IDE之一,非常經(jīng)典。(Borland Turbo C,Turbo Pascal,Borland C++ 3.1,等都是經(jīng)典) JCreator是我當(dāng)用java語(yǔ)言開(kāi)發(fā)的時(shí)候,用到的。我用它的原因是,它非常小,非常干凈,比eclipse用起來(lái)清爽多了。可惜它發(fā)展的不怎么樣。 除了上面4個(gè),我還常用editplus,notepad++和vi等編輯器。nodepad重點(diǎn)在語(yǔ)言加亮,editplus在于它非常小巧,功能強(qiáng)大,非常清爽,是我開(kāi)發(fā)必備的工具。因?yàn)橐T趌inux下修改數(shù)據(jù),所以vi也是常用之一,可惜只用它皮毛。 現(xiàn)在vs的版本是2013,從2012提供了python插件。python開(kāi)發(fā)者們有福了。
|