出处: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));
好了以上就是最核心部分,下面我贴图上我游戏里面的聊天效果: