【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
复制代码

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
复制代码

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_
复制代码

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)
{
    
}
复制代码

其中重要的设定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));

好了以上就是最核心部分,下面我贴图上我游戏里面的聊天效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值