专职C++

不能停止的脚步

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

常用链接

留言簿(28)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

#

一切又归零了。不解释什么!
无所谓得,无所谓失
有任性,有责任
2016终于开始。
posted @ 2016-03-11 00:07 冬瓜 阅读(2027) | 评论 (0)编辑 收藏

好久没有来,露个脸!
posted @ 2015-04-02 17:59 冬瓜 阅读(4074) | 评论 (0)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(7153) | 评论 (0)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(9141) | 评论 (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 冬瓜 阅读(3420) | 评论 (3)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(1617) | 评论 (0)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(1819) | 评论 (0)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(2871) | 评论 (0)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(2092) | 评论 (0)编辑 收藏

本文地址:http://www.cppblog.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 冬瓜 阅读(2847) | 评论 (2)编辑 收藏

仅列出标题
共17页: First 3 4 5 6 7 8 9 10 11 Last