• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            專職C++

            不能停止的腳步

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              163 Posts :: 7 Stories :: 135 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(28)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            #

            一切又歸零了。不解釋什么!
            無所謂得,無所謂失
            有任性,有責任
            2016終于開始。
            posted @ 2016-03-11 00:07 冬瓜 閱讀(2029) | 評論 (0)編輯 收藏

            好久沒有來,露個臉!
            posted @ 2015-04-02 17:59 冬瓜 閱讀(4077) | 評論 (0)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/09/03/208216.html
            本文基于cocos2dx 3.2
            cocos2dx 提供了一個基于xml的用戶數據存貯類,給基于cocos2dx開發的用戶數據存貯,這個類名就是UserDefault,在cocos2dx 2.x中是CCUserDefault。我的程序用的就是這個,但是最近老出錯,于是分析源代碼,發現了一個讓我震驚的東西。經過分析,發現用UserDefault每讀寫一次數據,都會創建一個tinyxml對象,然后讀取xml內容。如果是寫數據,還是寫入xml一次。下面是對應的代碼:
            讀取key,所以各種讀取key的操作,都是類似這樣。
            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;
            }
             關于getXMLNodeForKey的實現
            /**
             * 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;
            }
            關于setValueForKey的實現
            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方法也有驚人的發現:
            void UserDefault::flush()
            {
            }
            它是一個空函數,也就是說,你在寫入數據的時候,會以為最后會通過flush才會寫入數據,沒想全錯了!
            如果你用它存貯比較多的字段時,你就會現,你悲劇了。
            幸好發現及時,這里不建議大家使用UserDefault做為你的數據存貯。
            可以可以用自定義的方式文件讀寫
            如可以通過標準的C讀寫 fopen,fwrite等或iostream也都可以,重點是讀寫的文件路徑,會有所不同,下面是得到文件路徑的例子
            std::string strFullFileName = FileUtils::getInstance()->getWritablePath() + DATA_FILE_NAME;

            最后:不要求寫太高質量的代碼,但也不要寫的太低質量了
            posted @ 2014-09-03 10:23 冬瓜 閱讀(7165) | 評論 (0)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/08/23/208104.html
            經過幾天的填坑,終于將現有的項目由cocos2dx 2.2.2移到cocos2dx 3.2,差點放棄3.2了,但在最后一刻,又把坑填平了。
            cocos2dx 2.x到3.x是一個巨大的變化,可以算是完全不同。以前的類名,全是CC開頭的,現在全部去掉了。很多enum都改用enum class了
            所以,你知道2.x,對不起,你比小白學習3.x更難。你用2.x的做法用在3.x,那就全是坑了...
            言歸正傳,
            2.x的時候,按鈕設置為Disabled的時候,是看不見。3.x的是沒有禁用狀態的,但是不會響應touch事件。
            在cocostudio UI編輯的時候,按鈕是三種狀態的(有三個不同狀態的圖片),但沒有相應改變狀態的函數
            于是,就分析源碼,發現它是在onPressStateChangedToDisabled();更改為禁用狀態的圖片。再找,是于
            在其基類的ui:Widget的setBright和setHighlight有調用這個onPressStateChangedToDisabled,但是setEnabled僅僅是改為了一個成員變化,
            所以你在這里設置disabled,就不會有任何效果。除了上面兩個函數之后,還有一個函數setBrightStyle是設置按鈕是普通狀態還是高亮狀態
            下面是BrightStyle的定義
                enum class BrightStyle
                {
                    NONE = -1,
                    NORMAL,
                    HIGHLIGHT
                };
            下面是一個包裝的禁用啟用的函數
            //設置按鈕禁用啟用狀態
            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);
            }
            }
            posted @ 2014-08-23 14:41 冬瓜 閱讀(9156) | 評論 (0)編輯 收藏

            結果是:大家不要采用3.x系列的cocos2dx,還是用2.2.x吧
            原因如下:
            1、坑非常多,多的讓你放棄
            2、兼容性非常不好,如果你是2.x的工程,還是用2.x的吧
            3、資料非常少,開發方提供了3.x版本,但是3.x的版本各項資料都非常欠缺!論壇上各種3.x的問題貼子,很多都沒人回答。
            4、3.x做了很多無所謂的精減,結果是,你用到這些他們精減的庫時,你只有去哭了。(你的開發環境不可能和他們的一樣,他們沒問題,你的一定會有問題)
            5、千萬不要拿來3.x做商業化的程序,會大大增加你的開發周期和成本。
            posted @ 2014-08-22 15:00 冬瓜 閱讀(3453) | 評論 (3)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/08/04/207906.html
            今天,有空翻了一下<C++Primer plus(第六版)>,看到里面有介紹新的for循環和初始化列表,但是我實現的動態數組XDynamicArray不支持這些新特性,沒辦法,只好進行改造了。
            首先是for循環,如下面的樣式
            for(auto e:stList)
            {
                cout<<e<<endl;
            }
            是于就各種google,和查找C++11的array的源代碼,總結:就是提供一個標準的iterator和begin,end這兩個方法,就可以了。
            是于定義了一個iterator
                //一個數組的Array的Iterator類
                /*
                    這里提供XArrayIterator這個類,目的是使得這里支持C++11的for循環
                
            */
                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(&paramArray)
                    {}

                    XArrayIterator(const XArrayIterator<Array> & paramR)
                        :m_Index(paramR.m_Index), m_Array(paramR.m_Array)
                    {}

                    XArrayIterator & operator = (const XArrayIterator<Array> & paramR)
                    {
                        if (this != &paramR)
                        {
                            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兩個方法
            typedef XArrayIterator<XDynamicArray<T> > iterator
                    /*這里定義begin和end主要有兩個目的
                        目的1:使它可以像標準STD容器那樣遍歷
                        目的2:使它可以支持C++11的for循環
                        例子:
                        XDynamicArray<int> st;
                        for(auto x:st)
                        {
                            cout<<x<<endl;
                        }
                    
            */
                    iterator begin() 
                    {
                        iterator stRet(thisthis->getFirstIndex());
                        return stRet;
                    }

                    iterator end() 
                    {
                        iterator stRet(this, ARRAY_INVALID_INDEX);
                        return stRet;
                    }
            這樣就可以了,測試通過。你們也可以試試。
            C++11的另一個特性,就是新初始化列表,如下面例子
            vector st {1,2,3,4,5};
            看起來有點意思,于是又google一下,翻閱了各位大神的貼子,最終找到,然后我就實現了。這部分需要使用C++11的initializer_list模板類,具體使用代碼如下。
                    //這個構造函數的定義,是為了實現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>
            上述代碼,已經放到我的開放庫中了,大家可以自行下載。我的開放代碼
            posted @ 2014-08-04 18:47 冬瓜 閱讀(1623) | 評論 (0)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/08/01/207880.html
            現在C++智能指針有無數個實現了,多一個也無所謂。哈。
            這個智能指針是專門為cocos2dx 2.2.x定制的。主要是為了方便使用,同時又要遵循現有的cocos2dx的內存管理。特實現這樣一個智能指針。在使用的時候不需要考慮retain或release操作,也不需要new或delete操作!
            下面是實現代碼
            //在很多時候,類的成員是CCObject的子對象,為了保證對其正常使用,又要遵循cocos2dx的內存管理,特實現了這樣的一個智能指針,方便使用。
            #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();
                    }
                    //重載賦值運算符
                    XCocosPtr & operator = (T * paramObject)
                    {
                        set(paramObject);
                        return *this;
                    }

                    XCocosPtr & operator = (XCocosPtr & paramObject)
                    {
                        set(paramObject.m_Object);
                        return *this;
                    }
                    //重載比較運算符
                    bool operator == (T * paramObject) const
                    {
                        return m_Object == paramObject;
                    }

                    bool operator != (T * paramObject) const
                    {
                        return m_Object != paramObject;
                    }
                    //重載*運算符
                    T & operator*()
                    {
                        return *m_Object;
                    }

                    const T & operator*() const
                    {
                        return *m_Object;
                    }
                    //重載->運算符,使其可以像指針那樣使用
                    T * operator ->()
                    {
                        return m_Object;
                    }

                    const T * operator ->() const
                    {
                        return m_Object;
                    }
                    //判斷對象是否為空
                    bool is_null() const
                    {
                        return m_Object == nullptr;
                    }
                    //判斷對象是否為不空
                    bool is_not_null() const
                    {
                        return m_Object != nullptr;
                    }
                    //創建對象 這里會使用調用對象的create來創建對象
                    T * create()
                    {
                        T * pNewObject = T::create();
                        set(pNewObject);
                        return pNewObject;
                    }
                    //設置對象
                    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();
                            }
                        }
                    }
                    //取對象
                    T * get()
                    {
                        return m_Object;
                    }
                    //這里沒有使用release這個名稱,是為了防止和object的release混淆
                    void ptr_release()
                    {
                        if (m_Object != nullptr)
                        {
                            m_Object->release();
                            m_Object = nullptr;
                        }
                    }
                private:
                    T * m_Object;
                };
            }
            #endif
            例子
            //類的數據成員定義:
            XCocosPtr<CCSprite> m_Sprite;
            //在init中
            m_Sprite = CCSprite::create("");
            //
            m_Sprite.create()
            posted @ 2014-08-01 11:30 冬瓜 閱讀(1829) | 評論 (0)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/07/25/207805.html
            用CCLabelTTF顯示的數字不好看,于是就想到用圖片來代理。目前網上的實現都是把每個數字做一個CCSprite組合的方式。但是我想,動態生成紋理的方式。沒有就只好自己手動寫一個。
            頭文件
            #ifndef _X_NUMBER_H_
            #define _X_NUMBER_H_
            #include <cocos2d.h>
            #include <xtype.h>
            namespace cocos2d
            {
                //基于圖片顯示的數字
                /*
                    這個類不是用一個一個數字拼起來,而是渲染成一個獨立的紋理
                    zdh::XDDWord是一個64位無符號整數
                
            */
                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
            {
                //--------------------------------------------------------------------------------------
                
            //從指定資源名稱構建
                int CCPictureNumber::BuildNumber(zdh::XDDWord paramNumber, const char * paramNumberResName)
                {
                    this->setNumber(paramNumber);
                    this->setNumberTexture(CCTextureCache::sharedTextureCache()->addImage(paramNumberResName));
                    return this->Build();
                }

                //--------------------------------------------------------------------------------------
                
            //從指定紋理構建
                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); //將整數轉換為字符串
                    int iNumCount = strNumber.getLength();   //取得字符個數
                    CCSize stSize = m_NumberTexture->getContentSize(); //取得紋理大小,要求紋理中每個數字都是等寬等高,并依照0123456789排列
                    int iNumWidth = (int)stSize.width / 10;    //紋理中每個數字的寬度
                    int iNumHeight = (int)stSize.height;    //紋理中每個數字的高度

                    CCRenderTexture * pRT = CCRenderTexture::create(iNumWidth * iNumCount, iNumHeight); //創建渲染紋理對象,并數字確定寬度
                    CCSprite * pSprite    = CCSprite::create(); //創建精靈對象,用于繪制數字
                    pSprite->setAnchorPoint(0, 0);
                    pSprite->setTexture(m_NumberTexture);
                    CCRect stRect;
                    pRT->begin();
                    for (int i = 0; i < iNumCount; i++)
                    {
                        int iNumber = strNumber[i] - '0';
                        //設置要顯示數字的紋理區域,這個區域是指參數中paramTexture中區域
                        stRect.setRect(iNumber * iNumWidth, 0, iNumWidth, iNumHeight);
                        pSprite->setTextureRect(stRect, false, stRect.size);
                        pSprite->setPosition(i * iNumWidth, 0);                  //計算顯示的偏移位置
                        pSprite->visit(); //渲染到pRT中
                    }
                    pRT->end();
                    //取得生成的紋理
                    this->setTexture(pRT->getSprite()->getTexture());
                    //設置顯示的內容
                    stRect.setRect(0, 0, iNumWidth * iNumCount, iNumHeight);
                    this->setTextureRect(stRect, false, stRect.size);
                    //默認的情況下,通過CCRenderTexture得到的紋理是倒立的,這里需要做一下翻轉
                    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;
                }

            }
            數字圖片文件

            使用例子
                    CCPictureNumber * pNum = CCPictureNumber::create();
                    
                    pNum->BuildNumber(1234567, "ui_play_num05.png");
                    pNum->setPosition(200, 200);
                    pNum->setAnchorPoint(0, 0);

                    this->addChild(pNum, 100);
            //
            posted @ 2014-07-25 15:35 冬瓜 閱讀(2884) | 評論 (0)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/07/23/207760.html
            使用cocostudio可以裝載編輯好的UI,但是過于復雜。特別是在加截UI后,發現觸屏事件有些問題。如果直接使用程序寫死加載UI又過于麻煩。花點時間,增加了一個基于ini的UI配置類,目前只實現了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    ·#冒號開頭表示從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
            相關用到的TTextIni和XAnsiString,參考我的開源代碼
            posted @ 2014-07-23 20:04 冬瓜 閱讀(2102) | 評論 (0)編輯 收藏

            本文地址:http://www.shnenglu.com/zdhsoft/archive/2014/07/23/207756.html
            這四個是我用的主要IDE。

            VS+Visual AssistX可以用無敵開形容,太強大了。雖然我只用來寫C++代碼。我個人覺得,應該沒有什么IDE可以超過它的。沒有什么好形容它的,就是一直在用它...

            Eclipse也是一個非常強的,除了java,它還可以是C++,lua,tcl,python,ActionScript3等語言的IDE,現在cocos2dx也基于它推出cocos2dx 3.x系列的lua語言IDE。最新版本是luna,但是這次感覺和以前有一個最大的變化就是Menu->Help->Install new software,以前你要裝C++,那需要到CDT的頁面找插件的更新地址,其它語言也是類似。但是這次它提供一個luna的插件鏈接,可以安裝各種你想要的eclipse插件,不用再一個一個找了。

            當然,一些不是eclipse一起開發的,就還是要用老方法了。在eclipse這個工具,又衍生出FlashBuilder和ADT這兩個目前比較常見的開發工具,一個用于開發Flash,一個用于開發Android。雖然它很NB,但是我也只是拿它打打醬油。另然,eclipse的工程文件,是讓我非常無語的地方,比起vs等IDE,復雜多了。它的重構功能,還不夠,這是兩點是我拿它打醬油的原因。

            C++Builder是我曾經用過的編輯器,它曾經是非常牛的。用它開發數據庫和windows應用,一個字,就是快。兼顧速度和可視開發以及C++,雖然比它的本尊delphi差些,也比那個時候的vc強很多,易用性不比vb差。C++Builder6最后一個值得懷念的,后面borland把它的根本開發工具賣了。最近最新的RAD Studio XE6也發布了,可以可視化開發Android和windows以及iOS應用,可惜bug太多,當玩具可以,不怕死的,可以拿它去開發商業軟件。如果你沒買正版,它們的代理會來找你麻煩。還有它的安裝文件巨大,你的C盤沒20G,就不要去試了。borland為什么會死,就是自己作死的。還有不得不提一下Turbo C 2.0,這是我用過最好的IDE之一,非常經典。(Borland Turbo C,Turbo Pascal,Borland C++ 3.1,等都是經典)

            JCreator是我當用java語言開發的時候,用到的。我用它的原因是,它非常小,非常干凈,比eclipse用起來清爽多了。可惜它發展的不怎么樣。

            除了上面4個,我還常用editplus,notepad++和vi等編輯器。nodepad重點在語言加亮,editplus在于它非常小巧,功能強大,非常清爽,是我開發必備的工具。因為要常在linux下修改數據,所以vi也是常用之一,可惜只用它皮毛。

            現在vs的版本是2013,從2012提供了python插件。python開發者們有福了。
            posted @ 2014-07-23 10:52 冬瓜 閱讀(2862) | 評論 (2)編輯 收藏

            僅列出標題
            共17頁: First 3 4 5 6 7 8 9 10 11 Last 
            免费精品99久久国产综合精品| 嫩草影院久久国产精品| 成人亚洲欧美久久久久| 伊人 久久 精品| 99久久99久久精品国产片| 久久综合噜噜激激的五月天| 日本精品一区二区久久久| 久久99热国产这有精品| 久久AV无码精品人妻糸列| 日韩欧美亚洲国产精品字幕久久久 | 久久精品国产一区二区电影| 浪潮AV色综合久久天堂| 狠狠人妻久久久久久综合| 97超级碰碰碰碰久久久久| 久久伊人五月丁香狠狠色| yy6080久久| 99久久精品九九亚洲精品| 久久亚洲AV成人出白浆无码国产| 91久久精品国产91性色也| 亚洲乱码精品久久久久.. | 亚洲午夜久久久精品影院| 伊人情人综合成人久久网小说| 色综合合久久天天给综看| 婷婷综合久久中文字幕| 乱亲女H秽乱长久久久| 久久亚洲熟女cc98cm| 性欧美大战久久久久久久| 99久久综合国产精品二区| 狠狠色噜噜狠狠狠狠狠色综合久久| 久久中文字幕人妻丝袜| 久久人人爽人人爽人人av东京热| 久久精品国产国产精品四凭 | 欧洲国产伦久久久久久久| 国产成人精品久久亚洲| 99国产精品久久久久久久成人热| 国内精品久久久久久野外| 久久久久久久久无码精品亚洲日韩 | 欧美久久综合性欧美| 日本久久久精品中文字幕| 日本精品久久久久中文字幕| 色综合色天天久久婷婷基地|