【cocos2d-x 手游研發小技巧(6)聊天系統+字體高亮】


轉載請注明出處:http://www.cnblogs.com/zisou/p/cocos2dxJQ-6.html

聊天系統在手機網游中是最常見的交互工具,大家在一起邊玩游戲邊聊天豈不樂哉;

廢話不多了,這里重點只介紹客戶端的代碼,首先輸入框肯定用CCEditBox的了,現在這個最好用;

直接貼已經寫好的代碼:

首先是ChatInput.cpp這個類,主要就是彈出一個輸入框,點擊后彈出虛擬鍵盤輸入完成后,點擊發送的功能;

ChatInput.h

#include "cocos2d.h"
#include "cocos-ext.h"
#include "string"
using namespace std;
USING_NS_CC;
USING_NS_CC_EXT;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS||CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
class ChatInput : public CCLayer,  public CCEditBoxDelegate
{
public:
    ChatInput();
    ~ChatInput();
    
    
    virtual bool init();
    CREATE_FUNC(ChatInput);
    
    // 需要重寫觸摸注冊函數,重新給定觸摸級別
    virtual void registerWithTouchDispatcher(void);
    // 重寫觸摸函數,永遠返回 true ,屏蔽其它層,達到 “模態” 效果
    bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
    void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);

    // 構架,並設置對話框背景圖片
    static ChatInput* create(const char* backgroundImage);
    
    //添加輸入框
    void addEditBox(int tag);
    void addEditBox(int tag,int maxlength);
    //點擊菜單按鈕的回調
    void buttonCallback(CCObject* pSender);
    
    // 為了在顯示層時之前的屬性生效,選擇在 onEnter 里動態展示
    virtual void onEnter();
    virtual void onExit();

    virtual void editBoxEditingDidBegin(cocos2d::extension::CCEditBox* editBox);
    virtual void editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox);
    virtual void editBoxTextChanged(cocos2d::extension::CCEditBox* editBox, const std::string& text);
    virtual void editBoxReturn(cocos2d::extension::CCEditBox* editBox);
    
//    virtual void keyboardWillShow(cocos2d::CCIMEKeyboardNotificationInfo& info);
//    virtual void keyboardDidShow(cocos2d::CCIMEKeyboardNotificationInfo& info);
//    virtual void keyboardWillHide(cocos2d::CCIMEKeyboardNotificationInfo& info);
//    virtual void keyboardDidHide(cocos2d::CCIMEKeyboardNotificationInfo& info);
    
    cocos2d::extension::CCEditBox* m_pEditName;
    
    void ShowChangeclass(CCObject *pSender);
    void toChangeclass(CCObject *pSender);
    
    void sendMsg(CCObject *pSender);
private:
    CCSize winSize;
    void menuToggleCallback(CCObject* pSender);
    
    void togai(float togai);
    
    // 文字內容兩邊的空白區
    int m_contentPadding;
    int m_contentPaddingTop;
    
    
    CC_SYNTHESIZE_RETAIN(CCMenu*, m__pMenu, MenuButton);
    CC_SYNTHESIZE_RETAIN(CCSprite*, m__sfBackGround, SpriteBackGround);
    CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m__s9BackGround, Sprite9BackGround);
    CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltTitle, LabelTitle);
    CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltContentText, LabelContentText);
    
    CC_SYNTHESIZE_RETAIN(CCSprite*, m__sTitle, SpriteTitle);
    
    CC_SYNTHESIZE_RETAIN(CCEditBox*, m__pEditBox, EditBox);
    
    
    
    CCRect thisRect;//彈框的rect
    CCRect getRect();
};

#endif
View Code

ChatInput.cpp

#include "ChatInput.h"
#include "../GameConfig.h"
#include "../Commen/PublicShowUI.h"
#include "../ImagePaths.h"
#include "../Commen/PublicDoFunc.h"
#include "../GameData/GlobalInfo.h"
#include "../ToDoCommen/ToDoSend.h"


#if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS||CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
ChatInput::ChatInput()
:m__pMenu(NULL)
,m_contentPadding(0)
,m_contentPaddingTop(0)
,m__sfBackGround(NULL)
,m__s9BackGround(NULL)
,m__ltContentText(NULL)
,m__ltTitle(NULL)

,m__sTitle(NULL)
,m__pEditBox(NULL)
{
    winSize = CCDirector::sharedDirector()->getWinSize();
    
    CCLog("ChatInput::ChatInput");
}



ChatInput::~ChatInput()
{
    CCLog("ChatInput::~ChatInput");
    CC_SAFE_RELEASE(m__pMenu);
    CC_SAFE_RELEASE(m__sfBackGround);
    CC_SAFE_RELEASE(m__s9BackGround);
    CC_SAFE_RELEASE(m__ltContentText);
    CC_SAFE_RELEASE(m__ltTitle);
    CC_SAFE_RELEASE(m__sTitle);
    
}


bool ChatInput::init()
{
    CCLog("ChatInput::init;");
    bool bRef = false;
    do
    {
        CC_BREAK_IF(!CCLayer::init());
        this->setContentSize(CCSizeZero);
        // 初始化需要的 Menu
        CCMenu* menu = CCMenu::create();
        menu->setPosition(CCPointZero);
        setMenuButton(menu);
        setTouchEnabled(true);
        bRef = true;
    } while (0);
    return bRef;
    
}

void ChatInput::registerWithTouchDispatcher()
{
    // 這里的觸摸優先級設置為 -128 這保證了,屏蔽下方的觸摸
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128, true);
}

bool ChatInput::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
    return true;
}

ChatInput* ChatInput::create(const char *backgroundImage)
{
    ChatInput* ml = ChatInput::create();
    return ml;
}

void ChatInput::addEditBox(int tag,int maxlength)
{
    CCEditBox* m_pEditBox = CCEditBox::create(CCSizeMake(300, 40), CCScale9Sprite::create(p_chat_input_bd));
    if(maxlength>0)
    {
        m_pEditBox->setMaxLength(maxlength);
    }
    m_pEditBox->setReturnType(kKeyboardReturnTypeDone);
    m_pEditBox->setDelegate(this); //必須加這一行,否則不能撲捉到editBoxEditingDidBegin等事件
    m_pEditBox->setFontColor(ccWHITE);
    //    m_pEditBox->setText("請輸入...");
    m_pEditBox->setTag(tag);
    
    
    CCMenuItemImage *button_chatclass = CCMenuItemImage::create(
                                                                p_chat_bt_qb0,
                                                                p_chat_bt_qb1,
                                                                p_chat_bt_qb1,
                                                                button_chatclass,
                                                                menu_selector(ChatInput::sendMsg));
    CCMenu* pMenu_button_chatclass= CCMenu::create(button_chatclass, NULL);
    pMenu_button_chatclass->setPosition(ccp(-30,m_pEditBox->getContentSize().height/2));
    m_pEditBox->addChild(pMenu_button_chatclass,111, BASEUI_CHAT_CLASS);
    
    
    setEditBox(m_pEditBox);
    
    //必須專門設置一次同layer級別一樣的優先級,否則不能觸發彈出鍵盤
    getEditBox()->setTouchPriority(111);
}

void ChatInput::sendMsg(CCObject *pSender)
{
    string nrstr = GlobalInfo::getInstance()->get_chatnrstr();
    if(nrstr.length()>0)
    {
        MainRoledata* roleinfo = GlobalInfo::getInstance()->get_mainrole();
        
//        if(roleinfo->user_level>10||roleinfo->User_zhiye=="天仙"||roleinfo->User_zhiye=="金仙")
//        {
            if(GlobalInfo::getInstance()->get_chatclassname()=="全部")
            {
                ToDoSend::send_sendMyMsg(CCString::create("888"),  CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create("0"));
                GlobalInfo::getInstance()->set_chat_close_flag(true);
            }
            else if(GlobalInfo::getInstance()->get_chatclassname()=="天仙")
            {
                if(roleinfo->User_zhiye=="天仙"||roleinfo->User_zhiye=="金仙")
                {
                    ToDoSend::send_sendMyMsg(CCString::create("888"),  CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create("0"));
                  GlobalInfo::getInstance()->set_chat_close_flag(true);
                }
                else
                {
                    GlobalInfo::getInstance()->set_showtipstring("晉升到天仙以上才能進行天仙傳音");
                    GlobalInfo::getInstance()->set_showtipflag(true);
                }
            }
            else if(GlobalInfo::getInstance()->get_chatclassname()=="金仙")
            {
                if(roleinfo->User_zhiye=="金仙")
                {
                      ToDoSend::send_sendMyMsg(CCString::create("888"),  CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create("0"));
                    GlobalInfo::getInstance()->set_chat_close_flag(true);
                    
                }
                else
                {
                    GlobalInfo::getInstance()->set_showtipstring("晉升到金仙以上才能進行金仙傳音");
                    GlobalInfo::getInstance()->set_showtipflag(true);
                }
            }
//        }
//        else
//        {
//            GlobalInfo::getInstance()->set_showtipstring("修煉到散仙10層才能使用傳音功能!");
//            GlobalInfo::getInstance()->set_showtipflag(true);
//        }
    }
    else
    {
        GlobalInfo::getInstance()->set_showtipstring("請輸入聊天內容");
        GlobalInfo::getInstance()->set_showtipflag(true);
    }
    
}


void ChatInput::ShowChangeclass(CCObject *pSender)
{
    //獲取原按鈕
    CCMenuItemImage *button = (CCMenuItemImage*)pSender;
    
    //    button->setNormalSpriteFrame(CCSpriteFrame::create(p_chat_bt_tx0, CCRectMake(0, 0, button->getContentSize().width,button->getContentSize().height)));
    //全部
    if(button->getChildByTag(BASEUI_CHAT_CHANGE_QB)!=NULL)
    {
        button->removeChildByTag(BASEUI_CHAT_CHANGE_QB);
    }
    else
    {
        CCMenuItemImage *button_class_qb= CCMenuItemImage::create(
                                                                  p_chat_bt_qb0,
                                                                  p_chat_bt_qb1,
                                                                  p_chat_bt_qb1,
                                                                  button_class_qb,
                                                                  menu_selector(ChatInput::toChangeclass));
        button_class_qb->setTag(BASEUI_CHAT_CHANGE_QB);
        CCMenu* pMenu_button_qb= CCMenu::create(button_class_qb, NULL);
        pMenu_button_qb->setPosition(ccp(button->getContentSize().width/2,button->getContentSize().height*1.45));
        button->addChild(pMenu_button_qb,111, BASEUI_CHAT_CHANGE_QB);
    }
    //散仙
    if(button->getChildByTag(BASEUI_CHAT_CHANGE_SX)!=NULL)
    {
        button->removeChildByTag(BASEUI_CHAT_CHANGE_SX);
    }
    else
    {
        CCMenuItemImage *button_class_sx= CCMenuItemImage::create(
                                                                  p_chat_bt_sx0,
                                                                  p_chat_bt_sx1,
                                                                  p_chat_bt_sx1,
                                                                  button_class_sx,
                                                                  menu_selector(ChatInput::toChangeclass));
        button_class_sx->setTag(BASEUI_CHAT_CHANGE_SX);
        CCMenu* pMenu_button_sx= CCMenu::create(button_class_sx, NULL);
        pMenu_button_sx->setPosition(ccp(button->getContentSize().width/2,button->getContentSize().height*2.4));
        button->addChild(pMenu_button_sx,111, BASEUI_CHAT_CHANGE_SX);
    }
    //天仙
    if(button->getChildByTag(BASEUI_CHAT_CHANGE_TX)!=NULL)
    {
        button->removeChildByTag(BASEUI_CHAT_CHANGE_TX);
    }
    else
    {
        CCMenuItemImage *button_class_tx= CCMenuItemImage::create(
                                                                  p_chat_bt_tx0,
                                                                  p_chat_bt_tx1,
                                                                  p_chat_bt_tx1,
                                                                  button_class_tx,
                                                                  menu_selector(ChatInput::toChangeclass));
        button_class_tx->setTag(BASEUI_CHAT_CHANGE_TX);
        CCMenu* pMenu_button_tx= CCMenu::create(button_class_tx, NULL);
        pMenu_button_tx->setPosition(ccp(button->getContentSize().width/2,button->getContentSize().height*3.4));
        button->addChild(pMenu_button_tx,111, BASEUI_CHAT_CHANGE_TX);
    }
    //金仙
    if(button->getChildByTag(BASEUI_CHAT_CHANGE_JX)!=NULL)
    {
        button->removeChildByTag(BASEUI_CHAT_CHANGE_JX);
    }
    else
    {
        CCMenuItemImage *button_class_jx= CCMenuItemImage::create(
                                                                  p_chat_bt_jx0,
                                                                  p_chat_bt_jx1,
                                                                  p_chat_bt_jx1,
                                                                  button_class_jx,
                                                                  menu_selector(ChatInput::toChangeclass));
        button_class_jx->setTag(BASEUI_CHAT_CHANGE_JX);
        CCMenu* pMenu_button_jx= CCMenu::create(button_class_jx, NULL);
        pMenu_button_jx->setPosition(ccp(button->getContentSize().width/2,button->getContentSize().height*4.4));
        button->addChild(pMenu_button_jx,111, BASEUI_CHAT_CHANGE_JX);
    }
}

void ChatInput::togai(float togai)
{
    //    this->getChildByTag(BASEUI_CHAT_CLASS)->setVisible(false);
    if(GlobalInfo::getInstance()->get_todo_changeChatClass_flag()==true)
    {
       
        CCPoint nowp = this->getChildByTag(BASEUI_CHAT_CLASS)->getPosition();
        this->removeChildByTag(BASEUI_CHAT_CLASS);
        if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_SX)
        {
            CCMenuItemImage *button_class_sx= CCMenuItemImage::create(
                                                                      p_chat_bt_sx0,
                                                                      p_chat_bt_sx1,
                                                                      p_chat_bt_sx1,
                                                                      this,
                                                                      menu_selector(ChatInput::ShowChangeclass));
            CCMenu* pMenu_button_sx= CCMenu::create(button_class_sx, NULL);
            pMenu_button_sx->setPosition(nowp);
            this->addChild(pMenu_button_sx,111, BASEUI_CHAT_CLASS);
        }
        else if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_QB)
        {
            CCMenuItemImage *button_class_qb= CCMenuItemImage::create(
                                                                      p_chat_bt_qb0,
                                                                      p_chat_bt_qb1,
                                                                      p_chat_bt_qb1,
                                                                      this,
                                                                      menu_selector(ChatInput::ShowChangeclass));
            CCMenu* pMenu_button_qb= CCMenu::create(button_class_qb, NULL);
            pMenu_button_qb->setPosition(nowp);
            this->addChild(pMenu_button_qb,111, BASEUI_CHAT_CLASS);
        }
        else if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_TX)
        {
            CCMenuItemImage *button_class_tx= CCMenuItemImage::create(
                                                                      p_chat_bt_tx0,
                                                                      p_chat_bt_tx1,
                                                                      p_chat_bt_tx1,
                                                                      this,
                                                                      menu_selector(ChatInput::ShowChangeclass));
            CCMenu* pMenu_button_tx= CCMenu::create(button_class_tx, NULL);
            pMenu_button_tx->setPosition(nowp);
            this->addChild(pMenu_button_tx,111, BASEUI_CHAT_CLASS);
        }
        else if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_JX)
        {
            CCMenuItemImage *button_class_jx= CCMenuItemImage::create(
                                                                      p_chat_bt_jx0,
                                                                      p_chat_bt_jx1,
                                                                      p_chat_bt_jx1,
                                                                      this,
                                                                      menu_selector(ChatInput::ShowChangeclass));
            CCMenu* pMenu_button_jx= CCMenu::create(button_class_jx, NULL);
            pMenu_button_jx->setPosition(nowp);
            this->addChild(pMenu_button_jx,111, BASEUI_CHAT_CLASS);
        }
                
        GlobalInfo::getInstance()->set_todo_changeChatClass_flag(false);
    }
    
}

void ChatInput::toChangeclass(CCObject *pSender)
{
    CCNode * nd = (CCNode*)pSender;
    int TAGS = nd->getTag();
    if(TAGS==BASEUI_CHAT_CHANGE_SX)
    {
        GlobalInfo::getInstance()->set_chatclassname("散仙");
    }
    else if(TAGS==BASEUI_CHAT_CHANGE_QB)
    {
        GlobalInfo::getInstance()->set_chatclassname("全部");
    }
    else if(TAGS==BASEUI_CHAT_CHANGE_TX)
    {
        GlobalInfo::getInstance()->set_chatclassname("天仙");
    }
    else if(TAGS==BASEUI_CHAT_CHANGE_JX)
    {
        GlobalInfo::getInstance()->set_chatclassname("金仙");
    }
    GlobalInfo::getInstance()->set_todo_changeChatClass_flag(true);
    GlobalInfo::getInstance()->set_todo_changeChatClass_int(nd->getTag());
}

void ChatInput::addEditBox(int tag)
{
    GlobalInfo::getInstance()->set_chatclassname("全部");
    CCEditBox* m_pEditBox = CCEditBox::create(CCSizeMake(210, 28), CCScale9Sprite::create(p_chat_input_bd));
    m_pEditBox->setMaxLength(120);
    m_pEditBox->setReturnType(kKeyboardReturnTypeDone);
    m_pEditBox->setDelegate(this); //必須加這一行,否則不能撲捉到editBoxEditingDidBegin等事件
    m_pEditBox->setFontColor(ccWHITE);
    //    m_pEditBox->setText("請輸入...");
    //    m_pEditBox->setFontSize(5);
    m_pEditBox->setTag(tag);
    //設置鍵盤輸入模式
    m_pEditBox->setInputMode(kEditBoxInputModeAny);
    
    CCMenuItemImage *button_chatclass = CCMenuItemImage::create(
                                                                p_chat_bt_qb0,
                                                                p_chat_bt_qb1,
                                                                p_chat_bt_qb1,
                                                                this,
                                                                menu_selector(ChatInput::ShowChangeclass));
    CCMenu* pMenu_button_chatclass= CCMenu::create(button_chatclass, NULL);
    pMenu_button_chatclass->setPosition(ccp(-button_chatclass->getContentSize().width*0.5,m_pEditBox->getContentSize().height/2));
    m_pEditBox->addChild(pMenu_button_chatclass,111, BASEUI_CHAT_CLASS);
    
    CCMenuItemImage *button_send = CCMenuItemImage::create(
                                                           p_caozuo_send0,
                                                           p_caozuo_send1,
                                                           p_caozuo_send1,
                                                           button_chatclass,
                                                           menu_selector(ChatInput::sendMsg));
    CCMenu* pMenu_button_send= CCMenu::create(button_send, NULL);
    pMenu_button_send->setPosition(ccp(m_pEditBox->getContentSize().width*1.15,m_pEditBox->getContentSize().height/2));
    m_pEditBox->addChild(pMenu_button_send,112, BASEUI_CHAT_SEND);
    
    setEditBox(m_pEditBox);
    
    m_pEditBox->schedule(schedule_selector(ChatInput::togai));
    
    //必須專門設置一次同layer級別一樣的優先級,否則不能觸發彈出鍵盤
    getEditBox()->setTouchPriority(-128);
}



void ChatInput::buttonCallback(CCObject *pSender){
    //    CCNode* node = dynamic_cast<CCNode*>(pSender);
    //    CCLog("menubutton tag: %d", node->getTag());
    //    if(node->getTag()==LAYER_HALL_EDITBOX_SEND){
    //        CCLog("發送:%s len=%d",getEditBox()->getText(),strlen(getEditBox()->getText()));
    //        const char* text = getEditBox()->getText();
    //        if(strlen(text)>0)
    //        {
    //            CCArray *data = CCArray::create();
    //            data->addObject(CCString::create(text));
    //            SocketThread::sharedSocketThread()->Send(EVENT_LOUDChatInput,data);
    //        }
    //    }else{
    //        CCLog("關閉");
    //    }
    //    if (m_callback && m_callbackListener){
    //        CCLog("調用注冊函數");
    //        (m_callbackListener->*m_callback)();
    //    }
    //    this->removeFromParentAndCleanup(true);
}


void ChatInput::onEnter()
{
    CCLayer::onEnter();
    
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    
    CCSize contentSize = getContentSize();
    
    
    // 顯示EditBox
    if (getEditBox())
    {
        CCSprite* ChatInputBg= CCSprite::create(p_login_zhanghu);
        getEditBox()->setAnchorPoint(CCPointZero);
        getEditBox()->setPosition(ccp(ChatInputBg->getPositionX(),ChatInputBg->getPositionY()+ChatInputBg->getContentSize().height+2.0f));
        this->addChild(getEditBox());
    }
    
    // 添加按鈕,並設置其位置
    if (getMenuButton()->getChildrenCount()>0)
    {
        //        CCLog("size=%d",getMenuButton()->getChildrenCount());
        float btnWidth = 100.0;
        //        CCLog("btnwidth=%f",btnWidth);
        CCArray* array = getMenuButton()->getChildren();
        CCObject* pObj = NULL;
        int i = 0;
        CCARRAY_FOREACH(array, pObj)
        {
            CCNode* node = (CCNode*) pObj;
            switch(i){
                case 0:
                    //                    CCLog("btn width=%f",node->getContentSize().width);
                    node->setAnchorPoint(CCPointZero);
                    node->setPosition(ccp(getEditBox()->getPositionX()+getEditBox()->getContentSize().width + 2.0f  , getEditBox()->getPositionY()));
                    break;
                case 1:
                    node->setPosition(ccp(getEditBox()->getPositionX()+240  , getEditBox()->getPositionY()));
                    break;
            }
            i++;
        }
        this->addChild(getMenuButton());
    }
    
    thisRect = getRect();
    
    
}

void ChatInput::editBoxEditingDidBegin(cocos2d::extension::CCEditBox* editBox)
{
    CCLog("editBox %p DidBegin !", editBox);
    //    editBox->setText("");
}

void ChatInput::editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox)
{
    CCLog("editBox %p DidEnd !", editBox);
}

void ChatInput::editBoxTextChanged(cocos2d::extension::CCEditBox* editBox, const std::string& text)
{
    CCLog("editBox %p TextChanged, text: %s ", editBox, text.c_str());
    GlobalInfo::getInstance()->set_chatnrstr(text.c_str());
}

void ChatInput::editBoxReturn(cocos2d::extension::CCEditBox* editBox)
{
    CCLog("->>>>>>>>>>>>>>>>> %d ",editBox->getTag());
    
    //    CCArray* arraylist = CCArray::create();
    //    arraylist->addObject(editBox);
    //    arraylist->addObject(CCString::create(editBox->getText()));
    if(editBox->getTag()==INPUT_NAME)
    {
        GlobalInfo::getInstance()->set_inputname_str(editBox->getText());
    }
    else
    {
        //        PublicDoFunc::toDoFuncN(LAYER_LOGIN,callfuncN_selector(LoginScenes::set_input_zhanghu),(CCNode*)editBox);
    }
}


CCRect ChatInput::getRect()
{
    //獲取精靈區域大小
    return CCRectMake(getEditBox()->getPositionX()- getEditBox()->getContentSize().width  * getEditBox()->getAnchorPoint().x,getEditBox()->getPositionY()-getEditBox()->getContentSize().height* getEditBox()->getAnchorPoint().y,getEditBox()->getContentSize().width+50.0f, getEditBox()->getContentSize().height);
}

void ChatInput::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
    CCPoint point = pTouch->getLocation();
    //    CCLog("%f,%f",thisRect.size.width,thisRect.size.height);
    point = this->convertToNodeSpace(point);
    if(this->thisRect.containsPoint(point)==false)
    {
        //播放點擊音效
        this->removeFromParentAndCleanup(true);
    }
}

void ChatInput::onExit()
{
    CCLog("ChatInput::onExit");
    CCLayer::onExit();
}
#endif
View Code

Ok,有了輸入框,下面重要的就是聊天界面了,大家都知道,通常普通的CCLabelTTF是很難實現和幫助我們完成

大量的自定義界面,字體渲染工作的(在3.0以前,目前3.0以上已經可以很好處理字體渲染,陰影等問題)。那么

我們就得做類似自定義的控件了,而且要作可插拔的控件。

接着我們說一下實現原理,圖示:

圖中主要用到了CCTableView,圖中有很多小細節需要去細化和完成,比如說:聊天顯示方式,下面的往往是

最后一條聊天信息,那就需要執行一下將最下面的一條信息設置為最下面;還有Cell里面的內容信息需要去

拼湊字符集去顯示!

先上代碼;

自定義TableView類 ChatTableView.h:

#ifndef _ChatTableView_
#define _ChatTableView_

#include "cocos-ext.h"
#include "cocos2d.h"
#include "string"
#include "../GameData/Msgdata.h"

using namespace std;

USING_NS_CC;
USING_NS_CC_EXT;

class ChatTableView :public CCLayer,CCTableViewDataSource,CCTableViewDelegate
{
public:

    
    vector<Msgdata> n_msglist;
    
    float n_w,n_h,one_h;
    CCTableView* pTableView;
    
    ChatTableView(CCSprite* sp,float w,float h,vector<Msgdata> msglist);
    ~ChatTableView(void);
    
  
    
    virtual void tableCellTouched(cocos2d::extension::CCTableView* table, cocos2d::extension::CCTableViewCell* cell);
    
    virtual cocos2d::CCSize cellSizeForTable(cocos2d::extension::CCTableView *table);
    
    virtual cocos2d::extension::CCTableViewCell* tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned int idx);
    
    virtual unsigned int numberOfCellsInTableView(cocos2d::extension::CCTableView *table);
    virtual CCSize tableCellSizeForIndex(CCTableView* table,unsigned int idx);
    virtual void scrollViewDidScroll(cocos2d::extension::CCScrollView* view){};
    virtual void scrollViewDidZoom(cocos2d::extension::CCScrollView* view);
    
    //高亮顯示。選中效果
    virtual void tableCellHighlight(CCTableView* table, CCTableViewCell* cell);
    
    /**
     * Delegate to respond a table cell release event
     *
     * @param table table contains the given cell
     * @param cell  cell that is pressed
     */
    virtual void tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell);

    
private:

};

#endif //_TIPS_FOR_STORY_
View Code

ChatTableView.cpp:

#include "ChatTableView.h"
#include "../ImagePaths.h"
#include "../VisibleRect.h"
#include "../Commen/PublicShowUI.h"
#include "../Commen/FontChina.h"
#include "../GameConfig.h"
#include "../Commen/PublicDoFunc.h"
#include "../GameData/GlobalInfo.h"
#include "../HttpCommen/HttpWebServer.h"
#include "../ServerAPI.h"

ChatTableView::ChatTableView(CCSprite* sp,float w,float h,vector<Msgdata> msglist)
{
    if(sp->getChildByTag(1)!=NULL)
    {
        sp->removeChildByTag(1);
    }
    n_w=w;
    n_h=h;
    one_h=16;
    n_msglist=msglist;
    
    pTableView= CCTableView::create(this, VisibleRect::getVisibleRect().size,NULL);
    pTableView->setDirection(kCCScrollViewDirectionVertical);

    pTableView->setDelegate(this);
    pTableView->setPosition(ccp(sp->getContentSize().width*0.04,sp->getContentSize().height*0.14));
    pTableView->reloadData();
    pTableView->setViewSize(CCSizeMake(sp->getContentSize().width*0.94,sp->getContentSize().height*0.80));
    pTableView->setContentSize(CCSizeMake(sp->getContentSize().width*0.94,sp->getContentSize().height*0.80));
    sp->addChild(pTableView,1,1);
}



void ChatTableView::tableCellTouched(cocos2d::extension::CCTableView* table, cocos2d::extension::CCTableViewCell* cell)
{
    CCLog("tableCellTouched");
    
}

CCSize ChatTableView::cellSizeForTable(cocos2d::extension::CCTableView *table)
{
    //計算出高度
//    
//    CCSize cellSize =CCSizeMake(n_w, 60);
    return CCSizeMake(0, 0);
}
CCSize ChatTableView::tableCellSizeForIndex(CCTableView* table,unsigned int idx)
{
//    CCLOG("size forindex==%d",idx);
    if(idx < n_msglist.size()-1)
    {
        idx += 1;
    }
    Msgdata ms;
    string chatnr = n_msglist.at(idx).MsgText;
    string ss1s = chatnr;
    
    int higth=-1;
    if(chatnr.size()>45)
    {
        higth=28;
    }
    else
    {
        higth=14;
    }
    return CCSizeMake(n_w,higth);
}
CCTableViewCell* ChatTableView::tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned int idx)
{
    CCTableViewCell *pcell = table->dequeueCell();
    if (!pcell)
    {
        pcell = new CCTableViewCell();
        pcell->autorelease();
    }
    
    pcell->removeAllChildren();
        
    Msgdata ms;
    string playername = n_msglist.at(idx).MyInfo;
    string chattype = n_msglist.at(idx).MsgType;
    string chatnr = n_msglist.at(idx).MsgText;
  
    chattype = "["+chattype+"]";
    playername = playername+":";
    CCLabelTTF* tf = CCLabelTTF::create(chattype.c_str(), "", 10);
    tf->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊
    tf->setColor(ccc3(250, 255, 240));
    tf->setAnchorPoint(CCPointZero);
    pcell->addChild(tf);
    CCLabelTTF* tf2 = CCLabelTTF::create(playername.c_str(), "", 10);
    tf2->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊
    tf2->setColor(ccc3(200, 255, 255));
    tf2->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width/2*1.1,tf->getContentSize().height/2));
    pcell->addChild(tf2);
    
    string st1,st2,st3;
    if(chatnr.size()>45)
    {
        st1 =  chatnr.substr(0,45);
        st2 =  chatnr.substr(45,chatnr.size());
        CCLabelTTF* tf3 = CCLabelTTF::create(st1.c_str(), "", 10);
        tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊
        tf3->setColor(ccc3(240, 255, 240));
        tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/2,tf->getContentSize().height/2));
        pcell->addChild(tf3);
        if(st2.size()>0)
        {
            CCLabelTTF* tf4 = CCLabelTTF::create(st2.c_str(), "", 10);
            tf4->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊
            tf4->setColor(ccc3(240, 255, 240));
            tf4->setPosition(ccp(tf->getPosition().x,tf->getPosition().y-tf4->getContentSize().height/2*1.3));
            pcell->addChild(tf4);
        }
        
    }
    else
    {
        CCLabelTTF* tf3 = CCLabelTTF::create(chatnr.c_str(), "", 10);
        tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊
        tf3->setColor(ccc3(240, 255, 240));
        tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/2,tf->getContentSize().height/2));
        pcell->addChild(tf3);
    }

    playername.clear();
    chattype.clear();
    chatnr.clear();
    if(idx==n_msglist.size())
    {
        n_msglist.clear();
    }

      return pcell;
}

unsigned int ChatTableView::numberOfCellsInTableView(cocos2d::extension::CCTableView *table)
{
    int count = -1;
    if(n_msglist.size()>0)
    {
        count =n_msglist.size();
    }
    else
    {
        count = 0;
    }
    return count;
}

void ChatTableView::scrollViewDidZoom(cocos2d::extension::CCScrollView* view)
{
    CCLOG("didzoom");
}

void ChatTableView::tableCellHighlight(CCTableView* table, CCTableViewCell* cell)
{
    
//    CCSprite* note = (CCSprite*)cell->getChildByTag(1);
//    CCMenuItemImage* image = (CCMenuItemImage*)note->getChildByTag(1);
//    image->selected();
    CCLOG("高亮");
}

/**
 * Delegate to respond a table cell release event
 *
 * @param table table contains the given cell
 * @param cell  cell that is pressed
 */
void ChatTableView::tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell)
{
//    CCSprite* note = (CCSprite*)cell->getChildByTag(1);
//    CCMenuItemImage* image = (CCMenuItemImage*)note->getChildByTag(1);
//    image->unselected();
    
    
    CCLOG("不高亮");
}



ChatTableView::~ChatTableView(void)
{
    
}
View Code

其中重要的設定Cell高度的tableCellSizeForIndex方法如下,需要多加一行,不然會錯亂:

CCSize ChatTableView::tableCellSizeForIndex(CCTableView* table,unsigned int idx)
{
    if(idx < n_msglist.size()-1)
    {
        idx += 1;
    }int higth=-1;
    if(chatnr.size()>45)
    {
        higth=28;
    }
    else
    {
        higth=14;
    }
    return CCSizeMake(n_w,higth);
}

自己拼裝的換行的方法,大家可以自己去寫自己的一套,原理思路就是這樣,沒多大變化,

主要就是計算各種坐標和字體長度:

    Msgdata ms;
    string playername = n_msglist.at(idx).MyInfo;
    string chattype = n_msglist.at(idx).MsgType;
    string chatnr = n_msglist.at(idx).MsgText;
chattype
= "["+chattype+"]"; playername = playername+":"; CCLabelTTF* tf = CCLabelTTF::create(chattype.c_str(), "", 10); tf->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊 tf->setColor(ccc3(250, 255, 240)); tf->setAnchorPoint(CCPointZero); pcell->addChild(tf); CCLabelTTF* tf2 = CCLabelTTF::create(playername.c_str(), "", 10); tf2->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊 tf2->setColor(ccc3(200, 255, 255)); tf2->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width/2*1.1,tf->getContentSize().height/2)); pcell->addChild(tf2); string st1,st2,st3; if(chatnr.size()>45) { st1 = chatnr.substr(0,45); st2 = chatnr.substr(45,chatnr.size()); CCLabelTTF* tf3 = CCLabelTTF::create(st1.c_str(), "", 10); tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊 tf3->setColor(ccc3(240, 255, 240)); tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/2,tf->getContentSize().height/2)); pcell->addChild(tf3); if(st2.size()>0) { CCLabelTTF* tf4 = CCLabelTTF::create(st2.c_str(), "", 10); tf4->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊 tf4->setColor(ccc3(240, 255, 240)); tf4->setPosition(ccp(tf->getPosition().x,tf->getPosition().y-tf4->getContentSize().height/2*1.3)); pcell->addChild(tf4); } } else { CCLabelTTF* tf3 = CCLabelTTF::create(chatnr.c_str(), "", 10); tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //對齊 tf3->setColor(ccc3(240, 255, 240)); tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/2,tf->getContentSize().height/2)); pcell->addChild(tf3); } playername.clear(); chattype.clear(); chatnr.clear(); if(idx==n_msglist.size()) { n_msglist.clear(); }

最后就是將這些寫好的小控件都展示出來了!畫背景,然后把TableView裝載進去了;

void ChatTips::updata_msglist()
{
     vector<Msgdata> msgdatalist_qb;
        //先解析出所有信息
        string spstr = "";
        vector<string> strlist = PublicCommen::split(GlobalInfo::getInstance()->get_chatreturnstr(),spstr);
        if(strlist.at(0).length()>0)
        {
            msgdatalist_qb =  JsonPush::ToGetMsgListdata(strlist.at(0));
            ChatTableView *tableview = new ChatTableView(this,this->getContentSize().width*0.9,this->getContentSize().height*0.9,msgdatalist_qb);
            tableview->pTableView->setContentOffset(ccp(0,this->getContentSize().height*0.05));
        }
        msgdatalist_qb.clear();
        strlist.clear();
}

顯示的時候注意要將最后一條聊天信息展示出來,用setContentOffset這個方法:

tableview->pTableView->setContentOffset(ccp(0,this->getContentSize().height*0.05));

好了以上就是最核心部分,下面我貼圖上我游戲里面的聊天效果:

下一篇我將介紹使用Lua做功能模塊更新拓展的技巧文章;

—————————————————————————————————————————————————————————————

ps:仙凡奇緣官網 http://www.xianfancoco.com

仙凡奇緣開發版1.0已上線:百度雲盤下載體驗

cocos2dxQQ交流群:41131516

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM