zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    狄利克雷卷积
    洛谷P2044 [NOI2012]随机数生成器
    Miller Rabin算法详解
    BZOJ3667: Rabin-Miller算法
    洛谷P3383 【模板】线性筛素数(Miller_Rabin)
    洛谷P3806 【模板】点分治1
    BZOJ1468: Tree
    Android Camera调用过程分析
    安卓开发37:自定义的HorizontalScrollView类,使其pageScroll的时候焦点不选中
    Android抖动动画
  • 原文地址:https://www.cnblogs.com/zisou/p/cocos2dxJQ-6.html
Copyright © 2011-2022 走看看