Cocos2d-x顯示中文與字幕滾動--之遊戲開發《趙雲要格鬥》(14),cocos2d捲軸

來源:互聯網
上載者:User

Cocos2d-x顯示中文與字幕滾動--之遊戲開發《趙雲要格鬥》(14),cocos2d捲軸

    這裡是林炳文Evankaka的部落格,歡迎大家前來討論與交流~~~~~~

    轉載請註明出處http://blog.csdn.net/evankaka
    本文將要解決Cocos2d-x中顯示中文時出現亂碼的情形,並且實現一個字幕滾動的功能,這個功能是通過遮罩來實現的。

      cocos2d-x版本:2.2.5

    工程環境:windows7+VS2010

    開啟檔案:將工程放在cocos2d-x安裝目錄下的project檔案夾下用VS開啟

先來看看效果:


       在windows環境下使用visual studio開發cocos2d-x,由於visual studio 預設編碼為GBK格式,而cocos2d-x引擎預設編碼為UTF-8,如果有用到中文,在遊戲運行時有可能會出現亂碼的情況,這個問題一般有三種解決方案,如下

    (1)將源碼檔案儲存為utf-8格式(不建議,治標不治本)

    (2)自己編寫編碼轉碼,在用到中文的地方手動轉換

    (3)將顯示文本單獨儲存為文字檔(該檔案編碼為utf-8),由系統統一模組管理文本讀取顯示,建議使用這種方式,便於後期系統維護,並實現國際化。(這裡沒寫了)

 第一種方式很簡單就不不介紹了,下面將對第2種進行介紹。第3種還沒寫好。

一、自己編寫編碼轉碼,在用到中文的地方手動轉換。

   cocos2d-x的開發包內建了用於編碼轉換的iconv庫,標頭檔"iconv.h"。iconv命令可以將一種已知的字元集檔案轉換成另一種已知的字元集檔案。它的作用是在多種國際編碼格式之間進行文本內碼的轉換。

1、 直接把代碼寫進要用到的地方

  如果是只能到一次的話,推薦可以這麼做。

(1)首先,建立一個工程,然後在HelloWorldScene.cpp中添加標頭檔#include"iconv/iconv.h"/,

(2)然後在HelloWorldScene.cpp添加全域函數(記得要把它們放在所有函數的最上頭,要不就是最上頭再定義函數一下)

bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen){iconv_t cd = iconv_open(to_charset, from_charset);if (cd == 0) return false;const char **pin = &inbuf;char **pout = &outbuf;memset(outbuf,0,outlen);size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);iconv_close(cd);return ret == (size_t)(-1) ? false : true;}std::string IConvConvert_GBKToUTF8(const std::string& str){const char* textIn = str.c_str();char textOut[256];bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);return ret ? std::string(textOut) : std::string();}

運行之後報錯:

error LNK2019:無法解析的外部符號 _libiconv_close

error LNK2019:無法解析的外部符號 _libiconv

error LNK2019:無法解析的外部符號 _libiconv_open

 fatal error LNK1120: 3個無法解析的外部命令

解決方案:因為你沒有加libiconv.lib檔案 

在工程屬性 ->配置屬性 ->連結器->輸入->附加依賴項添加libiconv.lib

如下:


 (3)用法:

在用到的地方,我這裡是在init()裡添加

std::string str =IConvConvert_GBKToUTF8("我是林炳文Evankaka~~\n歡迎來到我的世界~~~");CCLabelTTF* pLabel = CCLabelTTF::create(str.c_str(), "Arial", 24);pLabel->setPosition(ccp(origin.x + visibleSize.width/2,origin.y + visibleSize.height - pLabel->getContentSize().height));this->addChild(pLabel, 1);

(4)效果:


2、單獨一個文字轉換檔 

    單獨儲存為 .h標頭檔,在使用到編碼轉換的cpp檔案include即可。如果要經常用到的話,建議用這種方法

記得在工程屬性 ->配置屬性 ->連結器->輸入->附加依賴項添加libiconv.lib

(1)在class檔案夾下建立一個名為ChineseString.h的檔案,並把它加到工程來。

#ifndef __ChineseString_H__  #define __ChineseString_H__  #include "iconv/iconv.h"//重點記得加上去static char g_GBKConvUTF8Buf[5000] = {0};class ChineseString{public:static const char* GBKToUTF8(const char *strChar)//將字串轉成UFT-8iconv_t iconvH;iconvH = iconv_open("utf-8","gb2312");if (iconvH == 0){return NULL;}size_t strLength = strlen(strChar);size_t outLength = strLength*4;size_t copyLength = outLength;memset(g_GBKConvUTF8Buf, 0, 5000);char* outbuf = (char*) malloc(outLength);char* pBuff = outbuf;memset(outbuf, 0, outLength);if (-1 == iconv(iconvH, &strChar, &strLength, &outbuf, &outLength)){iconv_close(iconvH);return NULL;}memcpy(g_GBKConvUTF8Buf,pBuff,copyLength);free(pBuff);iconv_close(iconvH);return g_GBKConvUTF8Buf;}};#endif  
(2)使用方法:

在要用到的地方先添加標頭檔ChineseString.h(記得加!)

然後是

CCLabelTTF* pLabel=CCLabelTTF::create(ChineseString::GBKToUTF8("<span style="font-family: Arial, Helvetica, sans-serif;">我是林炳文Evankaka~~\n歡迎來到我的世界~~~</span>"), "Arial", 24);<pre name="code" class="cpp">        pLabel->setPosition(ccp(origin.x + visibleSize.width/2,origin.y + visibleSize.height - pLabel->getContentSize().height));this->addChild(pLabel, 1);

(3)效果

二、字幕滾動

    字幕滾動應該是要在一個範圍內可見的,出了這個範圍就不可見了,這裡實現其實很簡單,就是通過CCClippingNode來實現的.CCClipingNode是一個可裁剪節點,簡單理解:

(1)首先它是一個節點,繼承於CCNode,所以它可以像普通節點一樣放入CCLayer,CCScene,CCNode中。

(2)作為節點,它就可以用作容器,承載其他節點和精靈。我把它叫底板。

(3)如果想要對一個節點進行裁剪,那需要給出裁剪的部分,這個裁剪地區,我把它叫模版。

所以CCClipingNode裁剪節點在組成上=底板+模版,而在顯示上=底板-模版。不知道這樣解釋會不會好理解一點。

這裡直接建了一個類,將上面建立的中文轉換標頭檔 用了進來,這是標頭檔 GameString.h

#ifndef __GameString_SCENE_H__#define __GameString_SCENE_H__#include "cocos2d.h"#include "cocos-ext.h"#include "ChineseString.h"#include "HelloWorldScene.h"//這是遊戲介面的標頭檔USING_NS_CC;USING_NS_CC_EXT;class GameString : public cocos2d::CCLayer{public:    virtual bool init();      static cocos2d::CCScene* scene();    CREATE_FUNC(GameString);//字幕滾動完成後調用void RollEnd();//跳過按鈕的事件void menuCloseCallback(CCObject* pSender);};#endif // __GameString_SCENE_H__

這是實現檔案 GameString.cpp

#include "GameString.h"CCScene* GameString::scene(){    CCScene *scene = CCScene::create();    GameString *layer = GameString::create();    scene->addChild(layer);    return scene;}bool GameString::init(){    if ( !CCLayer::init() )    {        return false;    }        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();//加個按鈕CCMenuItemImage *pCloseItem = CCMenuItemImage::create("exct.png","exct.png",this,menu_selector(GameString::menuCloseCallback));pCloseItem->setPosition(ccp( visibleSize.width -80 ,visibleSize.height-60));CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);pMenu->setPosition(CCPointZero);this->addChild(pMenu, 1);  //加背景    CCSprite* pSprite = CCSprite::create("enter.png");    pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));    this->addChild(pSprite, 0);//建立要顯示的文字CCLabelTTF* pLabel=CCLabelTTF::create(ChineseString::GBKToUTF8("我是林炳文Evankaka~~\n這是遊戲《趙雲要格鬥》\n歡迎來到我的世界~~~\n我是林炳文Evankaka~~\n這是遊戲《趙雲要格鬥》\n歡迎來到我的世界~~~\n我是林炳文Evankaka~~\n這是遊戲《趙雲要格鬥》"),"Arial",25);pLabel->setAnchorPoint(CCPointZero);ccColor3B color = ccc3(255,255,0);pLabel->setColor(color);pLabel->setPosition(ccp(50, -200));//Y軸注意為負,X軸對應下面的point[4]的50,讓他們對齊//繪製裁剪地區CCDrawNode* shap = CCDrawNode::create();CCPoint point[4] = {ccp(50,0), ccp(400,0), ccp(400,200), ccp(50,200)};//可以根據文字適當修改下大小shap->drawPolygon(point,4,ccc4f(255,255,255,255),0, ccc4f(255,255,255,255));//繪製四邊形////建立遮罩CCClippingNode* pClip = CCClippingNode::create();pClip->setInverted(false);pClip->setStencil(shap);//一定要有,要不會報錯pClip->addChild(pLabel);this->addChild(pClip);//開始讓字幕滾動啦CCMoveBy* moveact=CCMoveBy::create(10.0f,CCPointMake(0,400));//10秒向上移動400CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(GameString::RollEnd));//建立回調動作,文字飄動完後CCActionInterval* act=CCSequence::create(moveact,callFunc,NULL);//建立連續動作pLabel->runAction(act);    return true;}void GameString::RollEnd(){CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());//進入遊戲主介面}void GameString::menuCloseCallback(CCObject* pSender){RollEnd();//點擊跳過直接進入遊戲主介面}

效果:

(1)字幕滾動完成後進入遊戲主介面


(2)點擊跳過直接進入遊戲主介面





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.