cocos2d-x 2.2.1 wp8好多BUG啊

cocos2d-x 2.2.1 wp8好多问题啊,请容许我抱怨下,如果是我个人问题请指出来

  1. 比如锁屏,再进来动画帧跳跃问题,直接在hello world上写一个图片永久旋转的demo, 进入后台一会再回来,结果动画林乱了,我也林乱了。
  2. 比如无法CCLabelTTF显示中文问题
  3. 比如CCLabelTTF设置好size无法自动换行问题
  4. 比如Box2d, ARM 无法真机编译运行问题
  5. 比如在720x1280 HTC手机上,三千多的手机,超级卡顿问题,就一张背景图哦,就一张,只能跑50帧,再加一张CCLayerColor, 游戏就废了,40几帧,同样在诺基亚520上,却比较流畅,林乱死了。

以上是我一个人运行hello world,几分钟就能发现的问题,同样代码在iOS,Android上,毫无压力整死了写都行。

求真相是我的个人问题还是质量问题?这应该不能称为Release版本吧。

这样的质量应该不是触控写的吧,应该是微软写的吧,如果不是触控写的,至少把下关,微软坑爹惯了。曾几何时看他们写的cocos2d-xna, 直接拷贝函数,翻写成C#,没有实现的函数就把代码注释掉,然后抛个异常在那,极度不负责任。

我也有中文问题,搞了一个星期了CCLabelTTF显示中文还是没有解决:6:

中文显示每个版本都这样 字符集问题 把中文放到xml里面读取就行了
自动换行的话可以加\n或者空格

中文问题很严重啊

中文乱码 在Resources/fonts下加入对应的ttf就可以 比如 黑体.ttf

中文字体清晰度不够,有点模糊了,然后就是cocosdenshion貌似有内存问题,某处没有释放内存

wp8中文字不能换行问题,以及在代码中加入中文无法显示的处理办法。仅供大家研究学习。

将下面代码添加到cocos2dx中 CCFreeTypeFont.cpp 文件中,
并且使用我下面提供的addword()方法。

/*
*add by Relvin
*/
//Relvin input start

int IsTextUTF8(const std::string &str)
{
//来自网络
int i;
int nBytes = 0;//{UFT8可用1-6个字节编码,ASCII用一个字节
unsigned char chr;
bool bAllAscii = true; //{如果全部都是ASCII, 说明不是UTF-8
for (i = 0; i < str.length(); i++)
{
chr = str*;
if ((chr & 0x80) != 0) // {判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx
bAllAscii = false;
if (nBytes == 0) //{如果不是ASCII码,应该是多字节符,计算字节数
{
if (chr >= 0x80)
{
if (chr >= 0xFC && chr <= 0xFD)
nBytes = 6;
else if (chr >= 0xF8)
nBytes = 5;
else if (chr >= 0xF0)
nBytes = 4;
else if (chr >= 0xE0)
nBytes = 3;
else if (chr >= 0xC0)
nBytes = 2;
else
{
return false;
}
nBytes–;
}
}
else //{多字节符的非首字节,应为 10xxxxxx
{
if ((chr & 0xC0) != 0x80)
{
return false;
}
nBytes–;
}
}

if (nBytes > 0) //{违返规则
{
    return false;
}

if (bAllAscii) //如果全部都是ASCII, 说明不是UTF-8
{
    return false;
}
return true;

}

std::wstring Acsi2WideByte(const std::string& strascii)
{//来自网络
int widesize = MultiByteToWideChar(CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0);
if (widesize == ERROR_NO_UNICODE_TRANSLATION)
{

}
if (widesize == 0)
{
    
}
std::vector<wchar_t> resultstring(widesize);
int convresult = MultiByteToWideChar(CP_ACP, 0, (char*)strascii.c_str(), -1, &resultstring, widesize);


if (convresult != widesize)
{
    
}

return std::wstring(&resultstring);

}

std::string Unicode2Utf8(const std::wstring& widestring)
{//来自网络
int utf8size = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, NULL, 0, NULL, NULL);
if (utf8size == 0)
{

}

std::vector<char> resultstring(utf8size);

int convresult = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, &resultstring, utf8size, NULL, NULL);

if (convresult != utf8size)
{
    
}

return std::string(&resultstring);

}

std::string ASCII2UTF_8(const std::string &strAsciiCode)
{//来自网络
std::string strRet("");
//
std::wstring wstr = Acsi2WideByte(strAsciiCode);
//
strRet = Unicode2Utf8(wstr);
return strRet;
}

int is_zh_ch(char p)
{
if (p >= 0x00 && p <= 0x7f)
{
return 0;
}
else
{
return 1;
}
}

bool is_en_ch(char p)
{
if ((p >= ‘a’ && p <= ‘z’) || (p >= ‘A’ && p <= ‘Z’))
{
return true;
}
return false;

}

std::string subString(std::string &str, int start, int end)
{//来自网络
if (typeid(str) == typeid(string) && str.length() > 0)
{
int len = str.length();
string tmp = “”;

    vector <string> dump;
    int i = 0;
    while (i < len)
    {
        if (is_zh_ch(str.at(i)) == 1)
        {
            if (i + 2 < len)
            {
                dump.push_back(str.substr(i, 3));
                i = i + 3;
            }
            else
            {
                dump.push_back(str.substr(i, len - i));
                break;
            }
        }
        else
        {
            dump.push_back(str.substr(i, 1));
            i = i + 1;
        }
    }
    int iDumpSize = dump.size();
    for (i = end - 1; i >= start; i--)
    {
        if (dump*.length() == 0)
        {
            break;
        }

        if (is_en_ch(dump*))
        {
            if (i + 1 > iDumpSize || !is_en_ch(dump*))
            {
                end = i;
                break;
            }
            else if ((i - 1 >= start) && (!is_en_ch(dump*)))
            {
                end = i - 1;
                break;
            }
        }
        else
        {
            end = i;
            break;
        }

    }
    CCLOG("Relvin >> end = %d", end);
    end = end > 0 ? end : iDumpSize;
    end = end > iDumpSize ? iDumpSize : end;
    CCLOG("Relvin >> end = %d", end);
    if (start<0 || start>end)
        return "";
    for (i = start; i <= end; i++)
    {
        tmp += dump*;
    }
    str = "";
    for (i = end + 1; i < iDumpSize; i++)
    {
        str += dump*;
    }
    return tmp;
}
else
{
    return "";
}

}

//Relvin input end
FT_Error CCFreeTypeFont::addWord(const std::string& word)
{
std::vector glyphs; // glyphs for the word
FT_BBox bbox; // bounding box containing all of the glyphs in the word
int maxWidth = m_inWidth ? m_inWidth : m_windowWidth;
std::string newWord;

if (m_currentLine->width > 0)
{
    newWord = ' ' + word;
}
else
{
    if (!IsTextUTF8(word))
    {
        newWord = ASCII2UTF_8(word);
    }
    else
    {
        newWord = word;
    }
    
}

FT_Error error = initWordGlyphs(glyphs, newWord, m_currentLine->pen);
if (!error)
{
    compute_bbox(glyphs, &bbox);
    if (m_currentLine->width == 0 || bbox.xMax <= maxWidth)
    {
        if (bbox.xMax > maxWidth && glyphs.size() > 2)
        {
            int strEnd = 0;
            for (int i = 0; i < glyphs.size(); i++)
            {
                if (glyphs*.pos.x >= maxWidth)
                {
                    strEnd = i - 3;
                    break;
                }

            }
            if (strEnd <= 0)
            {
                strEnd = glyphs.size() - 2;
            }
            
            std::string tmpString = subString(newWord, 0, strEnd);
            m_currentLine->pen.x = 0;
            CCLOG("Relvin >> tmpString = %s >>>>> %d", tmpString.c_str(), strEnd);
            addWord(tmpString);
            endLine();
            newLine();
            CCLOG("Relvin >> newWord = %s  ", newWord.c_str());
            addWord(newWord);

        }
        else
        {
            m_currentLine->glyphs.insert(m_currentLine->glyphs.end(), glyphs.begin(), glyphs.end());
            if (m_currentLine->width == 0)
            {
                m_currentLine->bbox = bbox;
            }
            else
            {
                m_currentLine->bbox.xMax = bbox.xMax;
            }
            m_currentLine->width = m_currentLine->bbox.xMax - m_currentLine->bbox.xMin;
        }
    }
    else
    {
        endLine();
        newLine();
        addWord(word);
    }
}
return error;

}


关于无法换行的问题:
因为引擎换行使用的是空格来判断,这个在英文版的可以,但中文一般都不存在空格的。引擎判断方法的实现在 CCFreeTypeFont::initGlyphs中

while ((pos = line.find_first_of(" ", prev)) != std::string::npos)


修改方法:

在CCFreeTypeFont.h里的CCFreeTypeFont类添加两个方法:

 <pre class="brush:cpp; toolbar: true; auto-links: false;">FT_Error addLine(const std::string& line);
 void endLine_chinese();

这两个方法的代码实现是:

void CCFreeTypeFont::endLine_chinese() 
{
    if(m_currentLine)
    {
        m_lines.push_back(m_currentLine);
        compute_bbox(m_currentLine->glyphs, &m_currentLine->bbox);
        m_currentLine->width = m_currentLine->bbox.xMax - m_currentLine->bbox.xMin;
        m_textWidth = max(m_textWidth,m_currentLine->bbox.xMax - m_currentLine->bbox.xMin);
        m_textHeight += m_lineHeight;
        m_currentLine = NULL;
    }
}
```




FT_Error CCFreeTypeFont::addLine(const std::string& line)
{
        wchar_t *       pwszBuffer = nullptr;

        int num_chars = line.size();
        int nBufLen = num_chars + 1;
        pwszBuffer = new wchar_t;
        if (!pwszBuffer)
        {
                return -1;
        }

        memset(pwszBuffer, 0, nBufLen);
        num_chars = MultiByteToWideChar(CP_UTF8, 0, line.c_str(), num_chars, pwszBuffer, nBufLen);
        pwszBuffer = '\0';

        int maxWidth = m_inWidth ? m_inWidth : m_windowWidth;

        newLine();
        FT_Vector pen = m_currentLine->pen;
        FT_GlyphSlot    slot = m_face->glyph;
        FT_UInt                 glyph_index;
        FT_UInt                 previous = 0;
        FT_Error                error = 0;
        unsigned int    numGlyphs = 0;

        FT_Bool useKerning = FT_HAS_KERNING(m_face);

        int n = 0;
        while (n < num_chars)
        {
                TGlyph glyph;

                /* convert character code to glyph index */
                FT_ULong c = pwszBuffer;
                glyph_index = FT_Get_Char_Index(m_face, c);

                if (useKerning && previous && glyph_index)
                {
                        FT_Vector  delta;
                        FT_Get_Kerning(m_face, previous, glyph_index,
                                FT_KERNING_DEFAULT, &delta);
                        pen.x += delta.x >> 6;
                }

                /* store current pen position */
                glyph.pos = pen;
                glyph.index = glyph_index;

                /* load glyph image into the slot without rendering */
                error = FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
                if (error)
                        continue;  /* ignore errors, jump to next glyph */

                /* extract glyph image and store it in our table */
                error = FT_Get_Glyph(m_face->glyph, &glyph.image);
                if (error)
                        continue;  /* ignore errors, jump to next glyph */

                /* translate the glyph image now */
                FT_Glyph_Transform(glyph.image, 0, &glyph.pos);

                /* increment pen position */
                pen.x += slot->advance.x >> 6;

                if (pen.x > maxWidth)
                {
                        m_currentLine->pen = pen;
                       
                        // endLine();
                        endLine_chinese();

                        newLine();
                        pen = m_currentLine->pen;
                        previous = 0;
                        n--;
                }
                else
                {
                        m_currentLine->glyphs.push_back(glyph);
                        /* record current glyph index */
                        previous = glyph_index;
                }
        }

        if (m_currentLine)
        {
                m_currentLine->pen = pen;
                
                //endLine();
                endLine_chinese();
        }

        CC_SAFE_DELETE_ARRAY(pwszBuffer);
        return error;
}
```


然后修改  CCFreeTypeFont::initGlyphs 的实现为:

FT_Error CCFreeTypeFont::initGlyphs(const char* text)
{
    FT_Error error = 0;
    std::stringstream stringStream(text);
    std::string line;
    vector lines;
    vector words;

    m_textWidth = 0;
    m_textHeight = 0;
    // the height of a line of text based on the max height of a glyph in the font size
    m_lineHeight = ((m_face->size->metrics.ascender) >> 6) - ((m_face->size->metrics.descender) >> 6);

    m_lines.clear();

    while (std::getline(stringStream, line) && !error)
    {
        addLine(line);
    }

    return error;
}
```

中文不显示我也遇到了,搞了好久,换一下字体试试,