转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-6.html

聊天系统在手机网游中是最常见的交互工具,大家在一起边玩游戏边聊天岂不乐哉;

废话不多了,这里重点只介绍客户端的代码,首先输入框肯定用CCEditBox的了,现在这个最好用;

直接贴已经写好的代码:

首先是ChatInput.cpp这个类,主要就是弹出一个输入框,点击后弹出虚拟键盘输入完成后,点击发送的功能;

ChatInput.h

  1. #include "cocos2d.h"
  2. #include "cocos-ext.h"
  3. #include "string"
  4. using namespace std;
  5. USING_NS_CC;
  6. USING_NS_CC_EXT;
  7. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS||CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  8. class ChatInput : public CCLayer, public CCEditBoxDelegate
  9. {
  10. public:
  11. ChatInput();
  12. ~ChatInput();
  13.  
  14. virtual bool init();
  15. CREATE_FUNC(ChatInput);
  16.  
  17. // 需要重写触摸注册函数,重新给定触摸级别
  18. virtual void registerWithTouchDispatcher(void);
  19. // 重写触摸函数,永远返回 true ,屏蔽其它层,达到 “模态” 效果
  20. bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
  21. void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
  22.  
  23. // 构架,并设置对话框背景图片
  24. static ChatInput* create(const char* backgroundImage);
  25.  
  26. //添加输入框
  27. void addEditBox(int tag);
  28. void addEditBox(int tag,int maxlength);
  29. //点击菜单按钮的回调
  30. void buttonCallback(CCObject* pSender);
  31.  
  32. // 为了在显示层时之前的属性生效,选择在 onEnter 里动态展示
  33. virtual void onEnter();
  34. virtual void onExit();
  35.  
  36. virtual void editBoxEditingDidBegin(cocos2d::extension::CCEditBox* editBox);
  37. virtual void editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox);
  38. virtual void editBoxTextChanged(cocos2d::extension::CCEditBox* editBox, const std::string& text);
  39. virtual void editBoxReturn(cocos2d::extension::CCEditBox* editBox);
  40.  
  41. // virtual void keyboardWillShow(cocos2d::CCIMEKeyboardNotificationInfo& info);
  42. // virtual void keyboardDidShow(cocos2d::CCIMEKeyboardNotificationInfo& info);
  43. // virtual void keyboardWillHide(cocos2d::CCIMEKeyboardNotificationInfo& info);
  44. // virtual void keyboardDidHide(cocos2d::CCIMEKeyboardNotificationInfo& info);
  45.  
  46. cocos2d::extension::CCEditBox* m_pEditName;
  47.  
  48. void ShowChangeclass(CCObject *pSender);
  49. void toChangeclass(CCObject *pSender);
  50.  
  51. void sendMsg(CCObject *pSender);
  52. private:
  53. CCSize winSize;
  54. void menuToggleCallback(CCObject* pSender);
  55.  
  56. void togai(float togai);
  57.  
  58. // 文字内容两边的空白区
  59. int m_contentPadding;
  60. int m_contentPaddingTop;
  61.  
  62. CC_SYNTHESIZE_RETAIN(CCMenu*, m__pMenu, MenuButton);
  63. CC_SYNTHESIZE_RETAIN(CCSprite*, m__sfBackGround, SpriteBackGround);
  64. CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m__s9BackGround, Sprite9BackGround);
  65. CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltTitle, LabelTitle);
  66. CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltContentText, LabelContentText);
  67.  
  68. CC_SYNTHESIZE_RETAIN(CCSprite*, m__sTitle, SpriteTitle);
  69.  
  70. CC_SYNTHESIZE_RETAIN(CCEditBox*, m__pEditBox, EditBox);
  71.  
  72. CCRect thisRect;//弹框的rect
  73. CCRect getRect();
  74. };
  75.  
  76. #endif

ChatInput.cpp

  1. #include "ChatInput.h"
  2. #include "../GameConfig.h"
  3. #include "../Commen/PublicShowUI.h"
  4. #include "../ImagePaths.h"
  5. #include "../Commen/PublicDoFunc.h"
  6. #include "../GameData/GlobalInfo.h"
  7. #include "../ToDoCommen/ToDoSend.h"
  8.  
  9. #if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS||CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  10. ChatInput::ChatInput()
  11. :m__pMenu(NULL)
  12. ,m_contentPadding()
  13. ,m_contentPaddingTop()
  14. ,m__sfBackGround(NULL)
  15. ,m__s9BackGround(NULL)
  16. ,m__ltContentText(NULL)
  17. ,m__ltTitle(NULL)
  18.  
  19. ,m__sTitle(NULL)
  20. ,m__pEditBox(NULL)
  21. {
  22. winSize = CCDirector::sharedDirector()->getWinSize();
  23.  
  24. CCLog("ChatInput::ChatInput");
  25. }
  26.  
  27. ChatInput::~ChatInput()
  28. {
  29. CCLog("ChatInput::~ChatInput");
  30. CC_SAFE_RELEASE(m__pMenu);
  31. CC_SAFE_RELEASE(m__sfBackGround);
  32. CC_SAFE_RELEASE(m__s9BackGround);
  33. CC_SAFE_RELEASE(m__ltContentText);
  34. CC_SAFE_RELEASE(m__ltTitle);
  35. CC_SAFE_RELEASE(m__sTitle);
  36.  
  37. }
  38.  
  39. bool ChatInput::init()
  40. {
  41. CCLog("ChatInput::init;");
  42. bool bRef = false;
  43. do
  44. {
  45. CC_BREAK_IF(!CCLayer::init());
  46. this->setContentSize(CCSizeZero);
  47. // 初始化需要的 Menu
  48. CCMenu* menu = CCMenu::create();
  49. menu->setPosition(CCPointZero);
  50. setMenuButton(menu);
  51. setTouchEnabled(true);
  52. bRef = true;
  53. } while ();
  54. return bRef;
  55.  
  56. }
  57.  
  58. void ChatInput::registerWithTouchDispatcher()
  59. {
  60. // 这里的触摸优先级设置为 -128 这保证了,屏蔽下方的触摸
  61. CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -, true);
  62. }
  63.  
  64. bool ChatInput::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
  65. {
  66. return true;
  67. }
  68.  
  69. ChatInput* ChatInput::create(const char *backgroundImage)
  70. {
  71. ChatInput* ml = ChatInput::create();
  72. return ml;
  73. }
  74.  
  75. void ChatInput::addEditBox(int tag,int maxlength)
  76. {
  77. CCEditBox* m_pEditBox = CCEditBox::create(CCSizeMake(, ), CCScale9Sprite::create(p_chat_input_bd));
  78. if(maxlength>)
  79. {
  80. m_pEditBox->setMaxLength(maxlength);
  81. }
  82. m_pEditBox->setReturnType(kKeyboardReturnTypeDone);
  83. m_pEditBox->setDelegate(this); //必须加这一行,否则不能扑捉到editBoxEditingDidBegin等事件
  84. m_pEditBox->setFontColor(ccWHITE);
  85. // m_pEditBox->setText("请输入...");
  86. m_pEditBox->setTag(tag);
  87.  
  88. CCMenuItemImage *button_chatclass = CCMenuItemImage::create(
  89. p_chat_bt_qb0,
  90. p_chat_bt_qb1,
  91. p_chat_bt_qb1,
  92. button_chatclass,
  93. menu_selector(ChatInput::sendMsg));
  94. CCMenu* pMenu_button_chatclass= CCMenu::create(button_chatclass, NULL);
  95. pMenu_button_chatclass->setPosition(ccp(-,m_pEditBox->getContentSize().height/));
  96. m_pEditBox->addChild(pMenu_button_chatclass,, BASEUI_CHAT_CLASS);
  97.  
  98. setEditBox(m_pEditBox);
  99.  
  100. //必须专门设置一次同layer级别一样的优先级,否则不能触发弹出键盘
  101. getEditBox()->setTouchPriority();
  102. }
  103.  
  104. void ChatInput::sendMsg(CCObject *pSender)
  105. {
  106. string nrstr = GlobalInfo::getInstance()->get_chatnrstr();
  107. if(nrstr.length()>)
  108. {
  109. MainRoledata* roleinfo = GlobalInfo::getInstance()->get_mainrole();
  110.  
  111. // if(roleinfo->user_level>10||roleinfo->User_zhiye=="天仙"||roleinfo->User_zhiye=="金仙")
  112. // {
  113. if(GlobalInfo::getInstance()->get_chatclassname()=="全部")
  114. {
  115. ToDoSend::send_sendMyMsg(CCString::create(""), CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create(""));
  116. GlobalInfo::getInstance()->set_chat_close_flag(true);
  117. }
  118. else if(GlobalInfo::getInstance()->get_chatclassname()=="天仙")
  119. {
  120. if(roleinfo->User_zhiye=="天仙"||roleinfo->User_zhiye=="金仙")
  121. {
  122. ToDoSend::send_sendMyMsg(CCString::create(""), CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create(""));
  123. GlobalInfo::getInstance()->set_chat_close_flag(true);
  124. }
  125. else
  126. {
  127. GlobalInfo::getInstance()->set_showtipstring("晋升到天仙以上才能进行天仙传音");
  128. GlobalInfo::getInstance()->set_showtipflag(true);
  129. }
  130. }
  131. else if(GlobalInfo::getInstance()->get_chatclassname()=="金仙")
  132. {
  133. if(roleinfo->User_zhiye=="金仙")
  134. {
  135. ToDoSend::send_sendMyMsg(CCString::create(""), CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create(""));
  136. GlobalInfo::getInstance()->set_chat_close_flag(true);
  137.  
  138. }
  139. else
  140. {
  141. GlobalInfo::getInstance()->set_showtipstring("晋升到金仙以上才能进行金仙传音");
  142. GlobalInfo::getInstance()->set_showtipflag(true);
  143. }
  144. }
  145. // }
  146. // else
  147. // {
  148. // GlobalInfo::getInstance()->set_showtipstring("修炼到散仙10层才能使用传音功能!");
  149. // GlobalInfo::getInstance()->set_showtipflag(true);
  150. // }
  151. }
  152. else
  153. {
  154. GlobalInfo::getInstance()->set_showtipstring("请输入聊天内容");
  155. GlobalInfo::getInstance()->set_showtipflag(true);
  156. }
  157.  
  158. }
  159.  
  160. void ChatInput::ShowChangeclass(CCObject *pSender)
  161. {
  162. //获取原按钮
  163. CCMenuItemImage *button = (CCMenuItemImage*)pSender;
  164.  
  165. // button->setNormalSpriteFrame(CCSpriteFrame::create(p_chat_bt_tx0, CCRectMake(0, 0, button->getContentSize().width,button->getContentSize().height)));
  166. //全部
  167. if(button->getChildByTag(BASEUI_CHAT_CHANGE_QB)!=NULL)
  168. {
  169. button->removeChildByTag(BASEUI_CHAT_CHANGE_QB);
  170. }
  171. else
  172. {
  173. CCMenuItemImage *button_class_qb= CCMenuItemImage::create(
  174. p_chat_bt_qb0,
  175. p_chat_bt_qb1,
  176. p_chat_bt_qb1,
  177. button_class_qb,
  178. menu_selector(ChatInput::toChangeclass));
  179. button_class_qb->setTag(BASEUI_CHAT_CHANGE_QB);
  180. CCMenu* pMenu_button_qb= CCMenu::create(button_class_qb, NULL);
  181. pMenu_button_qb->setPosition(ccp(button->getContentSize().width/,button->getContentSize().height*1.45));
  182. button->addChild(pMenu_button_qb,, BASEUI_CHAT_CHANGE_QB);
  183. }
  184. //散仙
  185. if(button->getChildByTag(BASEUI_CHAT_CHANGE_SX)!=NULL)
  186. {
  187. button->removeChildByTag(BASEUI_CHAT_CHANGE_SX);
  188. }
  189. else
  190. {
  191. CCMenuItemImage *button_class_sx= CCMenuItemImage::create(
  192. p_chat_bt_sx0,
  193. p_chat_bt_sx1,
  194. p_chat_bt_sx1,
  195. button_class_sx,
  196. menu_selector(ChatInput::toChangeclass));
  197. button_class_sx->setTag(BASEUI_CHAT_CHANGE_SX);
  198. CCMenu* pMenu_button_sx= CCMenu::create(button_class_sx, NULL);
  199. pMenu_button_sx->setPosition(ccp(button->getContentSize().width/,button->getContentSize().height*2.4));
  200. button->addChild(pMenu_button_sx,, BASEUI_CHAT_CHANGE_SX);
  201. }
  202. //天仙
  203. if(button->getChildByTag(BASEUI_CHAT_CHANGE_TX)!=NULL)
  204. {
  205. button->removeChildByTag(BASEUI_CHAT_CHANGE_TX);
  206. }
  207. else
  208. {
  209. CCMenuItemImage *button_class_tx= CCMenuItemImage::create(
  210. p_chat_bt_tx0,
  211. p_chat_bt_tx1,
  212. p_chat_bt_tx1,
  213. button_class_tx,
  214. menu_selector(ChatInput::toChangeclass));
  215. button_class_tx->setTag(BASEUI_CHAT_CHANGE_TX);
  216. CCMenu* pMenu_button_tx= CCMenu::create(button_class_tx, NULL);
  217. pMenu_button_tx->setPosition(ccp(button->getContentSize().width/,button->getContentSize().height*3.4));
  218. button->addChild(pMenu_button_tx,, BASEUI_CHAT_CHANGE_TX);
  219. }
  220. //金仙
  221. if(button->getChildByTag(BASEUI_CHAT_CHANGE_JX)!=NULL)
  222. {
  223. button->removeChildByTag(BASEUI_CHAT_CHANGE_JX);
  224. }
  225. else
  226. {
  227. CCMenuItemImage *button_class_jx= CCMenuItemImage::create(
  228. p_chat_bt_jx0,
  229. p_chat_bt_jx1,
  230. p_chat_bt_jx1,
  231. button_class_jx,
  232. menu_selector(ChatInput::toChangeclass));
  233. button_class_jx->setTag(BASEUI_CHAT_CHANGE_JX);
  234. CCMenu* pMenu_button_jx= CCMenu::create(button_class_jx, NULL);
  235. pMenu_button_jx->setPosition(ccp(button->getContentSize().width/,button->getContentSize().height*4.4));
  236. button->addChild(pMenu_button_jx,, BASEUI_CHAT_CHANGE_JX);
  237. }
  238. }
  239.  
  240. void ChatInput::togai(float togai)
  241. {
  242. // this->getChildByTag(BASEUI_CHAT_CLASS)->setVisible(false);
  243. if(GlobalInfo::getInstance()->get_todo_changeChatClass_flag()==true)
  244. {
  245.  
  246. CCPoint nowp = this->getChildByTag(BASEUI_CHAT_CLASS)->getPosition();
  247. this->removeChildByTag(BASEUI_CHAT_CLASS);
  248. if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_SX)
  249. {
  250. CCMenuItemImage *button_class_sx= CCMenuItemImage::create(
  251. p_chat_bt_sx0,
  252. p_chat_bt_sx1,
  253. p_chat_bt_sx1,
  254. this,
  255. menu_selector(ChatInput::ShowChangeclass));
  256. CCMenu* pMenu_button_sx= CCMenu::create(button_class_sx, NULL);
  257. pMenu_button_sx->setPosition(nowp);
  258. this->addChild(pMenu_button_sx,, BASEUI_CHAT_CLASS);
  259. }
  260. else if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_QB)
  261. {
  262. CCMenuItemImage *button_class_qb= CCMenuItemImage::create(
  263. p_chat_bt_qb0,
  264. p_chat_bt_qb1,
  265. p_chat_bt_qb1,
  266. this,
  267. menu_selector(ChatInput::ShowChangeclass));
  268. CCMenu* pMenu_button_qb= CCMenu::create(button_class_qb, NULL);
  269. pMenu_button_qb->setPosition(nowp);
  270. this->addChild(pMenu_button_qb,, BASEUI_CHAT_CLASS);
  271. }
  272. else if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_TX)
  273. {
  274. CCMenuItemImage *button_class_tx= CCMenuItemImage::create(
  275. p_chat_bt_tx0,
  276. p_chat_bt_tx1,
  277. p_chat_bt_tx1,
  278. this,
  279. menu_selector(ChatInput::ShowChangeclass));
  280. CCMenu* pMenu_button_tx= CCMenu::create(button_class_tx, NULL);
  281. pMenu_button_tx->setPosition(nowp);
  282. this->addChild(pMenu_button_tx,, BASEUI_CHAT_CLASS);
  283. }
  284. else if(GlobalInfo::getInstance()->get_todo_changeChatClass_int()==BASEUI_CHAT_CHANGE_JX)
  285. {
  286. CCMenuItemImage *button_class_jx= CCMenuItemImage::create(
  287. p_chat_bt_jx0,
  288. p_chat_bt_jx1,
  289. p_chat_bt_jx1,
  290. this,
  291. menu_selector(ChatInput::ShowChangeclass));
  292. CCMenu* pMenu_button_jx= CCMenu::create(button_class_jx, NULL);
  293. pMenu_button_jx->setPosition(nowp);
  294. this->addChild(pMenu_button_jx,, BASEUI_CHAT_CLASS);
  295. }
  296.  
  297. GlobalInfo::getInstance()->set_todo_changeChatClass_flag(false);
  298. }
  299.  
  300. }
  301.  
  302. void ChatInput::toChangeclass(CCObject *pSender)
  303. {
  304. CCNode * nd = (CCNode*)pSender;
  305. int TAGS = nd->getTag();
  306. if(TAGS==BASEUI_CHAT_CHANGE_SX)
  307. {
  308. GlobalInfo::getInstance()->set_chatclassname("散仙");
  309. }
  310. else if(TAGS==BASEUI_CHAT_CHANGE_QB)
  311. {
  312. GlobalInfo::getInstance()->set_chatclassname("全部");
  313. }
  314. else if(TAGS==BASEUI_CHAT_CHANGE_TX)
  315. {
  316. GlobalInfo::getInstance()->set_chatclassname("天仙");
  317. }
  318. else if(TAGS==BASEUI_CHAT_CHANGE_JX)
  319. {
  320. GlobalInfo::getInstance()->set_chatclassname("金仙");
  321. }
  322. GlobalInfo::getInstance()->set_todo_changeChatClass_flag(true);
  323. GlobalInfo::getInstance()->set_todo_changeChatClass_int(nd->getTag());
  324. }
  325.  
  326. void ChatInput::addEditBox(int tag)
  327. {
  328. GlobalInfo::getInstance()->set_chatclassname("全部");
  329. CCEditBox* m_pEditBox = CCEditBox::create(CCSizeMake(, ), CCScale9Sprite::create(p_chat_input_bd));
  330. m_pEditBox->setMaxLength();
  331. m_pEditBox->setReturnType(kKeyboardReturnTypeDone);
  332. m_pEditBox->setDelegate(this); //必须加这一行,否则不能扑捉到editBoxEditingDidBegin等事件
  333. m_pEditBox->setFontColor(ccWHITE);
  334. // m_pEditBox->setText("请输入...");
  335. // m_pEditBox->setFontSize(5);
  336. m_pEditBox->setTag(tag);
  337. //设置键盘输入模式
  338. m_pEditBox->setInputMode(kEditBoxInputModeAny);
  339.  
  340. CCMenuItemImage *button_chatclass = CCMenuItemImage::create(
  341. p_chat_bt_qb0,
  342. p_chat_bt_qb1,
  343. p_chat_bt_qb1,
  344. this,
  345. menu_selector(ChatInput::ShowChangeclass));
  346. CCMenu* pMenu_button_chatclass= CCMenu::create(button_chatclass, NULL);
  347. pMenu_button_chatclass->setPosition(ccp(-button_chatclass->getContentSize().width*0.5,m_pEditBox->getContentSize().height/));
  348. m_pEditBox->addChild(pMenu_button_chatclass,, BASEUI_CHAT_CLASS);
  349.  
  350. CCMenuItemImage *button_send = CCMenuItemImage::create(
  351. p_caozuo_send0,
  352. p_caozuo_send1,
  353. p_caozuo_send1,
  354. button_chatclass,
  355. menu_selector(ChatInput::sendMsg));
  356. CCMenu* pMenu_button_send= CCMenu::create(button_send, NULL);
  357. pMenu_button_send->setPosition(ccp(m_pEditBox->getContentSize().width*1.15,m_pEditBox->getContentSize().height/));
  358. m_pEditBox->addChild(pMenu_button_send,, BASEUI_CHAT_SEND);
  359.  
  360. setEditBox(m_pEditBox);
  361.  
  362. m_pEditBox->schedule(schedule_selector(ChatInput::togai));
  363.  
  364. //必须专门设置一次同layer级别一样的优先级,否则不能触发弹出键盘
  365. getEditBox()->setTouchPriority(-);
  366. }
  367.  
  368. void ChatInput::buttonCallback(CCObject *pSender){
  369. // CCNode* node = dynamic_cast<CCNode*>(pSender);
  370. // CCLog("menubutton tag: %d", node->getTag());
  371. // if(node->getTag()==LAYER_HALL_EDITBOX_SEND){
  372. // CCLog("发送:%s len=%d",getEditBox()->getText(),strlen(getEditBox()->getText()));
  373. // const char* text = getEditBox()->getText();
  374. // if(strlen(text)>0)
  375. // {
  376. // CCArray *data = CCArray::create();
  377. // data->addObject(CCString::create(text));
  378. // SocketThread::sharedSocketThread()->Send(EVENT_LOUDChatInput,data);
  379. // }
  380. // }else{
  381. // CCLog("关闭");
  382. // }
  383. // if (m_callback && m_callbackListener){
  384. // CCLog("调用注册函数");
  385. // (m_callbackListener->*m_callback)();
  386. // }
  387. // this->removeFromParentAndCleanup(true);
  388. }
  389.  
  390. void ChatInput::onEnter()
  391. {
  392. CCLayer::onEnter();
  393.  
  394. CCSize winSize = CCDirector::sharedDirector()->getWinSize();
  395.  
  396. CCSize contentSize = getContentSize();
  397.  
  398. // 显示EditBox
  399. if (getEditBox())
  400. {
  401. CCSprite* ChatInputBg= CCSprite::create(p_login_zhanghu);
  402. getEditBox()->setAnchorPoint(CCPointZero);
  403. getEditBox()->setPosition(ccp(ChatInputBg->getPositionX(),ChatInputBg->getPositionY()+ChatInputBg->getContentSize().height+2.0f));
  404. this->addChild(getEditBox());
  405. }
  406.  
  407. // 添加按钮,并设置其位置
  408. if (getMenuButton()->getChildrenCount()>)
  409. {
  410. // CCLog("size=%d",getMenuButton()->getChildrenCount());
  411. float btnWidth = 100.0;
  412. // CCLog("btnwidth=%f",btnWidth);
  413. CCArray* array = getMenuButton()->getChildren();
  414. CCObject* pObj = NULL;
  415. int i = ;
  416. CCARRAY_FOREACH(array, pObj)
  417. {
  418. CCNode* node = (CCNode*) pObj;
  419. switch(i){
  420. case :
  421. // CCLog("btn width=%f",node->getContentSize().width);
  422. node->setAnchorPoint(CCPointZero);
  423. node->setPosition(ccp(getEditBox()->getPositionX()+getEditBox()->getContentSize().width + 2.0f , getEditBox()->getPositionY()));
  424. break;
  425. case :
  426. node->setPosition(ccp(getEditBox()->getPositionX()+ , getEditBox()->getPositionY()));
  427. break;
  428. }
  429. i++;
  430. }
  431. this->addChild(getMenuButton());
  432. }
  433.  
  434. thisRect = getRect();
  435.  
  436. }
  437.  
  438. void ChatInput::editBoxEditingDidBegin(cocos2d::extension::CCEditBox* editBox)
  439. {
  440. CCLog("editBox %p DidBegin !", editBox);
  441. // editBox->setText("");
  442. }
  443.  
  444. void ChatInput::editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox)
  445. {
  446. CCLog("editBox %p DidEnd !", editBox);
  447. }
  448.  
  449. void ChatInput::editBoxTextChanged(cocos2d::extension::CCEditBox* editBox, const std::string& text)
  450. {
  451. CCLog("editBox %p TextChanged, text: %s ", editBox, text.c_str());
  452. GlobalInfo::getInstance()->set_chatnrstr(text.c_str());
  453. }
  454.  
  455. void ChatInput::editBoxReturn(cocos2d::extension::CCEditBox* editBox)
  456. {
  457. CCLog("->>>>>>>>>>>>>>>>> %d ",editBox->getTag());
  458.  
  459. // CCArray* arraylist = CCArray::create();
  460. // arraylist->addObject(editBox);
  461. // arraylist->addObject(CCString::create(editBox->getText()));
  462. if(editBox->getTag()==INPUT_NAME)
  463. {
  464. GlobalInfo::getInstance()->set_inputname_str(editBox->getText());
  465. }
  466. else
  467. {
  468. // PublicDoFunc::toDoFuncN(LAYER_LOGIN,callfuncN_selector(LoginScenes::set_input_zhanghu),(CCNode*)editBox);
  469. }
  470. }
  471.  
  472. CCRect ChatInput::getRect()
  473. {
  474. //获取精灵区域大小
  475. 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);
  476. }
  477.  
  478. void ChatInput::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
  479. {
  480. CCPoint point = pTouch->getLocation();
  481. // CCLog("%f,%f",thisRect.size.width,thisRect.size.height);
  482. point = this->convertToNodeSpace(point);
  483. if(this->thisRect.containsPoint(point)==false)
  484. {
  485. //播放点击音效
  486. this->removeFromParentAndCleanup(true);
  487. }
  488. }
  489.  
  490. void ChatInput::onExit()
  491. {
  492. CCLog("ChatInput::onExit");
  493. CCLayer::onExit();
  494. }
  495. #endif

Ok,有了输入框,下面重要的就是聊天界面了,大家都知道,通常普通的CCLabelTTF是很难实现和帮助我们完成

大量的自定义界面,字体渲染工作的(在3.0以前,目前3.0以上已经可以很好处理字体渲染,阴影等问题)。那么

我们就得做类似自定义的控件了,而且要作可插拔的控件。

接着我们说一下实现原理,图示:

图中主要用到了CCTableView,图中有很多小细节需要去细化和完成,比如说:聊天显示方式,下面的往往是

最后一条聊天信息,那就需要执行一下将最下面的一条信息设置为最下面;还有Cell里面的内容信息需要去

拼凑字符集去显示!

先上代码;

自定义TableView类 ChatTableView.h:

  1. #ifndef _ChatTableView_
  2. #define _ChatTableView_
  3.  
  4. #include "cocos-ext.h"
  5. #include "cocos2d.h"
  6. #include "string"
  7. #include "../GameData/Msgdata.h"
  8.  
  9. using namespace std;
  10.  
  11. USING_NS_CC;
  12. USING_NS_CC_EXT;
  13.  
  14. class ChatTableView :public CCLayer,CCTableViewDataSource,CCTableViewDelegate
  15. {
  16. public:
  17.  
  18. vector<Msgdata> n_msglist;
  19.  
  20. float n_w,n_h,one_h;
  21. CCTableView* pTableView;
  22.  
  23. ChatTableView(CCSprite* sp,float w,float h,vector<Msgdata> msglist);
  24. ~ChatTableView(void);
  25.  
  26. virtual void tableCellTouched(cocos2d::extension::CCTableView* table, cocos2d::extension::CCTableViewCell* cell);
  27.  
  28. virtual cocos2d::CCSize cellSizeForTable(cocos2d::extension::CCTableView *table);
  29.  
  30. virtual cocos2d::extension::CCTableViewCell* tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned int idx);
  31.  
  32. virtual unsigned int numberOfCellsInTableView(cocos2d::extension::CCTableView *table);
  33. virtual CCSize tableCellSizeForIndex(CCTableView* table,unsigned int idx);
  34. virtual void scrollViewDidScroll(cocos2d::extension::CCScrollView* view){};
  35. virtual void scrollViewDidZoom(cocos2d::extension::CCScrollView* view);
  36.  
  37. //高亮显示。选中效果
  38. virtual void tableCellHighlight(CCTableView* table, CCTableViewCell* cell);
  39.  
  40. /**
  41. * Delegate to respond a table cell release event
  42. *
  43. * @param table table contains the given cell
  44. * @param cell cell that is pressed
  45. */
  46. virtual void tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell);
  47.  
  48. private:
  49.  
  50. };
  51.  
  52. #endif //_TIPS_FOR_STORY_

ChatTableView.cpp:

  1. #include "ChatTableView.h"
  2. #include "../ImagePaths.h"
  3. #include "../VisibleRect.h"
  4. #include "../Commen/PublicShowUI.h"
  5. #include "../Commen/FontChina.h"
  6. #include "../GameConfig.h"
  7. #include "../Commen/PublicDoFunc.h"
  8. #include "../GameData/GlobalInfo.h"
  9. #include "../HttpCommen/HttpWebServer.h"
  10. #include "../ServerAPI.h"
  11.  
  12. ChatTableView::ChatTableView(CCSprite* sp,float w,float h,vector<Msgdata> msglist)
  13. {
  14. if(sp->getChildByTag()!=NULL)
  15. {
  16. sp->removeChildByTag();
  17. }
  18. n_w=w;
  19. n_h=h;
  20. one_h=;
  21. n_msglist=msglist;
  22.  
  23. pTableView= CCTableView::create(this, VisibleRect::getVisibleRect().size,NULL);
  24. pTableView->setDirection(kCCScrollViewDirectionVertical);
  25.  
  26. pTableView->setDelegate(this);
  27. pTableView->setPosition(ccp(sp->getContentSize().width*0.04,sp->getContentSize().height*0.14));
  28. pTableView->reloadData();
  29. pTableView->setViewSize(CCSizeMake(sp->getContentSize().width*0.94,sp->getContentSize().height*0.80));
  30. pTableView->setContentSize(CCSizeMake(sp->getContentSize().width*0.94,sp->getContentSize().height*0.80));
  31. sp->addChild(pTableView,,);
  32. }
  33.  
  34. void ChatTableView::tableCellTouched(cocos2d::extension::CCTableView* table, cocos2d::extension::CCTableViewCell* cell)
  35. {
  36. CCLog("tableCellTouched");
  37.  
  38. }
  39.  
  40. CCSize ChatTableView::cellSizeForTable(cocos2d::extension::CCTableView *table)
  41. {
  42. //计算出高度
  43. //
  44. // CCSize cellSize =CCSizeMake(n_w, 60);
  45. return CCSizeMake(, );
  46. }
  47. CCSize ChatTableView::tableCellSizeForIndex(CCTableView* table,unsigned int idx)
  48. {
  49. // CCLOG("size forindex==%d",idx);
  50. if(idx < n_msglist.size()-)
  51. {
  52. idx += ;
  53. }
  54. Msgdata ms;
  55. string chatnr = n_msglist.at(idx).MsgText;
  56. string ss1s = chatnr;
  57.  
  58. int higth=-;
  59. if(chatnr.size()>)
  60. {
  61. higth=;
  62. }
  63. else
  64. {
  65. higth=;
  66. }
  67. return CCSizeMake(n_w,higth);
  68. }
  69. CCTableViewCell* ChatTableView::tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned int idx)
  70. {
  71. CCTableViewCell *pcell = table->dequeueCell();
  72. if (!pcell)
  73. {
  74. pcell = new CCTableViewCell();
  75. pcell->autorelease();
  76. }
  77.  
  78. pcell->removeAllChildren();
  79.  
  80. Msgdata ms;
  81. string playername = n_msglist.at(idx).MyInfo;
  82. string chattype = n_msglist.at(idx).MsgType;
  83. string chatnr = n_msglist.at(idx).MsgText;
  84.  
  85. chattype = "["+chattype+"]";
  86. playername = playername+":";
  87. CCLabelTTF* tf = CCLabelTTF::create(chattype.c_str(), "", );
  88. tf->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  89. tf->setColor(ccc3(, , ));
  90. tf->setAnchorPoint(CCPointZero);
  91. pcell->addChild(tf);
  92. CCLabelTTF* tf2 = CCLabelTTF::create(playername.c_str(), "", );
  93. tf2->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  94. tf2->setColor(ccc3(, , ));
  95. tf2->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width/*1.1,tf->getContentSize().height/));
  96. pcell->addChild(tf2);
  97.  
  98. string st1,st2,st3;
  99. if(chatnr.size()>)
  100. {
  101. st1 = chatnr.substr(,);
  102. st2 = chatnr.substr(,chatnr.size());
  103. CCLabelTTF* tf3 = CCLabelTTF::create(st1.c_str(), "", );
  104. tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  105. tf3->setColor(ccc3(, , ));
  106. tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
  107. pcell->addChild(tf3);
  108. if(st2.size()>)
  109. {
  110. CCLabelTTF* tf4 = CCLabelTTF::create(st2.c_str(), "", );
  111. tf4->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  112. tf4->setColor(ccc3(, , ));
  113. tf4->setPosition(ccp(tf->getPosition().x,tf->getPosition().y-tf4->getContentSize().height/*1.3));
  114. pcell->addChild(tf4);
  115. }
  116.  
  117. }
  118. else
  119. {
  120. CCLabelTTF* tf3 = CCLabelTTF::create(chatnr.c_str(), "", );
  121. tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  122. tf3->setColor(ccc3(, , ));
  123. tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
  124. pcell->addChild(tf3);
  125. }
  126.  
  127. playername.clear();
  128. chattype.clear();
  129. chatnr.clear();
  130. if(idx==n_msglist.size())
  131. {
  132. n_msglist.clear();
  133. }
  134.  
  135. return pcell;
  136. }
  137.  
  138. unsigned int ChatTableView::numberOfCellsInTableView(cocos2d::extension::CCTableView *table)
  139. {
  140. int count = -;
  141. if(n_msglist.size()>)
  142. {
  143. count =n_msglist.size();
  144. }
  145. else
  146. {
  147. count = ;
  148. }
  149. return count;
  150. }
  151.  
  152. void ChatTableView::scrollViewDidZoom(cocos2d::extension::CCScrollView* view)
  153. {
  154. CCLOG("didzoom");
  155. }
  156.  
  157. void ChatTableView::tableCellHighlight(CCTableView* table, CCTableViewCell* cell)
  158. {
  159.  
  160. // CCSprite* note = (CCSprite*)cell->getChildByTag(1);
  161. // CCMenuItemImage* image = (CCMenuItemImage*)note->getChildByTag(1);
  162. // image->selected();
  163. CCLOG("高亮");
  164. }
  165.  
  166. /**
  167. * Delegate to respond a table cell release event
  168. *
  169. * @param table table contains the given cell
  170. * @param cell cell that is pressed
  171. */
  172. void ChatTableView::tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell)
  173. {
  174. // CCSprite* note = (CCSprite*)cell->getChildByTag(1);
  175. // CCMenuItemImage* image = (CCMenuItemImage*)note->getChildByTag(1);
  176. // image->unselected();
  177.  
  178. CCLOG("不高亮");
  179. }
  180.  
  181. ChatTableView::~ChatTableView(void)
  182. {
  183.  
  184. }

其中重要的设定Cell高度的tableCellSizeForIndex方法如下,需要多加一行,不然会错乱:

  1. CCSize ChatTableView::tableCellSizeForIndex(CCTableView* table,unsigned int idx)
  2. {
  3. if(idx < n_msglist.size()-)
  4. {
  5. idx += ;
  6. }int higth=-;
  7. if(chatnr.size()>)
  8. {
  9. higth=;
  10. }
  11. else
  12. {
  13. higth=;
  14. }
  15. return CCSizeMake(n_w,higth);
  16. }

自己拼装的换行的方法,大家可以自己去写自己的一套,原理思路就是这样,没多大变化,

主要就是计算各种坐标和字体长度:

  1. Msgdata ms;
  2. string playername = n_msglist.at(idx).MyInfo;
  3. string chattype = n_msglist.at(idx).MsgType;
  4. string chatnr = n_msglist.at(idx).MsgText;
  5. chattype = "["+chattype+"]";
  6. playername = playername+":";
  7. CCLabelTTF* tf = CCLabelTTF::create(chattype.c_str(), "", );
  8. tf->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  9. tf->setColor(ccc3(, , ));
  10. tf->setAnchorPoint(CCPointZero);
  11. pcell->addChild(tf);
  12. CCLabelTTF* tf2 = CCLabelTTF::create(playername.c_str(), "", );
  13. tf2->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  14. tf2->setColor(ccc3(, , ));
  15. tf2->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width/*1.1,tf->getContentSize().height/));
  16. pcell->addChild(tf2);
  17.  
  18. string st1,st2,st3;
  19. if(chatnr.size()>)
  20. {
  21. st1 = chatnr.substr(,);
  22. st2 = chatnr.substr(,chatnr.size());
  23. CCLabelTTF* tf3 = CCLabelTTF::create(st1.c_str(), "", );
  24. tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  25. tf3->setColor(ccc3(, , ));
  26. tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
  27. pcell->addChild(tf3);
  28. if(st2.size()>)
  29. {
  30. CCLabelTTF* tf4 = CCLabelTTF::create(st2.c_str(), "", );
  31. tf4->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  32. tf4->setColor(ccc3(, , ));
  33. tf4->setPosition(ccp(tf->getPosition().x,tf->getPosition().y-tf4->getContentSize().height/*1.3));
  34. pcell->addChild(tf4);
  35. }
  36.  
  37. }
  38. else
  39. {
  40. CCLabelTTF* tf3 = CCLabelTTF::create(chatnr.c_str(), "", );
  41. tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
  42. tf3->setColor(ccc3(, , ));
  43. tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
  44. pcell->addChild(tf3);
  45. }
  46.  
  47. playername.clear();
  48. chattype.clear();
  49. chatnr.clear();
  50. if(idx==n_msglist.size())
  51. {
  52. n_msglist.clear();
  53. }

最后就是将这些写好的小控件都展示出来了!画背景,然后把TableView装载进去了;

  1. void ChatTips::updata_msglist()
  2. {
  3.      vector<Msgdata> msgdatalist_qb;
  4. //先解析出所有信息
  5. string spstr = "⊙";
  6. vector<string> strlist = PublicCommen::split(GlobalInfo::getInstance()->get_chatreturnstr(),spstr);
  7. if(strlist.at().length()>)
  8. {
  9. msgdatalist_qb = JsonPush::ToGetMsgListdata(strlist.at());
  10. ChatTableView *tableview = new ChatTableView(this,this->getContentSize().width*0.9,this->getContentSize().height*0.9,msgdatalist_qb);
  11. tableview->pTableView->setContentOffset(ccp(,this->getContentSize().height*0.05));
  12. }
  13. msgdatalist_qb.clear();
  14. strlist.clear();
  1. }

显示的时候注意要将最后一条聊天信息展示出来,用setContentOffset这个方法:

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

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

下一篇我将介绍使用Lua做功能模块更新拓展的技巧文章;

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

ps:仙凡奇缘官网 http://www.xianfancoco.com

仙凡奇缘开发版1.0已上线:百度云盘下载体验

cocos2dxQQ交流群:41131516

【cocos2d-x 手游研发小技巧(6)聊天系统+字体高亮】的更多相关文章

  1. 【cocos2d-x 手游研发小技巧(8)通讯的数据压缩与解压 】

    今天说一下手机游戏通讯协议中的数据问题,大量的数据将给服务器端和客户端带来很大的压力,一般来说. 转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-8 ...

  2. 【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】

    直插主题了,今天写了一下午,早就想要写这类似东西的,首先我不会选用CCLabelAtlas了,我直接用帧图片做. 首先我们要准备素材,我先把素材帖出来给大家: 这个是一张比较全的素材图,它包含了扣血的 ...

  3. 【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】

    游戏开发中常遇到资源保护的问题. 目前游戏开发中常加密的文件类型有:图片,Lua文件,音频等文件,而其实加密也是一把双刃剑. 需要安全那就得耗费一定的资源去实现它.目前网上也有用TexturePack ...

  4. 【cocos2d-x 手游研发小技巧(5)获取网络图片缓存并展示】

    今天是年前最后一天上班了,最后一天上班,祝大家马上有各种东西,最后一天也给写一点干货,就是获取网络图片: 经过自己简单封装了一下,实现了获取网络图片,按照比例展示出来,实现方法是cocos2dx - ...

  5. 【cocos2d-x 手游研发小技巧(4)与Android混编实现换“头像图片”】

    cocos2dx在android平台上的游戏开发中往往会遇到一些混编需求,如: 比方有的社区类游戏需要用到更换玩家的“头像”操作,其实就是调用android servers服务里面的本地图片,以及选取 ...

  6. 【cocos2d-x 手游研发小技巧(3)Android界面分辨率适配方案】

    先感叹一下吧~~android的各种分辨率各种适配虐我千百遍,每次新项目我依旧待它如初恋···· 每家公司都有自己项目工程适配的方案,这种东西就是没有最好,只有最适合!!! 这次新项目专项针对andr ...

  7. 【cocos2d-x 手游研发小技巧(2)循环无限滚动的登陆背景】

    原创文章,转载请附上链接:http://www.cnblogs.com/zisou/p/cocos2d-xARPG6.html 首先让大家知道我们想要实现的最终效果是什么样的? 看一个<逆天仙魔 ...

  8. 【cocos2d-x 手游研发----目录】

    感谢大家一直支持我写这样一系列的博客,从中我自己也获益良多,cocos2d-x这样一款非常棒的引擎,是值得我们去学习和分享的,谈到分享,那我就把这套写了差不多一两个月的框架给大家开源下载,写的很一般, ...

  9. 【cocos2d-x 手游研发----地图活起来了】

    谈到地图不少人都说要做地图编辑器了,但是我暂时绕过这一步,如果不用寻路地图就不能移动?寻路就是会绕过障碍物的算法. 我做了一个简单的地图的思想,就是地图分层3层:背景层.可行区域层.遮罩层,但是地图就 ...

随机推荐

  1. 安装运行Rovio

    https://github.com/ethz-asl/rovio下载代码,该存储库包含ROVIO(Robust Visual Inertial Odometry)框架. https://github ...

  2. 在控制台远程连接mysql数据库时,出现ERROR 2049 (HY000)错误

    问题的原因是,你本地的数据库版本过高,而远程的数据库版本低. 解决方法:在连接时加上  --skip-secure-auth 参数就可以了. mysql -h主机 -u用户名 -p密码 --skip- ...

  3. Adplus 抓取Crash Dump

    本实例在win8.1 安装window kits https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit 1 ...

  4. g++报错原因分析:expected class-name before ‘{’ token

    今天写程序的时候, 遇到这样一个错误expected class-name before ‘{’ token 最后发现原来是我的头文件声明没有加. 继承时不要忘记加基类的头文件 错误: class F ...

  5. cnn 反向bp这个地方怎么推导??

  6. part1:13-linux编译器GCC

    Gcc特点 Gcc基本用法 1.gcc的概念 GCC(GNU Compiler Collection,GNU编译器套装),是一款由GNU开发的编程语言编译器.GCC原名为GNU C 语言编译器,因为它 ...

  7. Python 版本之 Anaconda

    https://www.anaconda.com/download/#linux Anaconda概述 Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windo ...

  8. 关于多系统跨浏览器 BrowserStack 的使用

    偶然在Scott Hanselman Blogs看到一篇关于 BrowserStack 博文,对于前端多浏览器测试. 现在拥有各自内核的浏览器越来越多,各自的特性也千差万别.如果作为一个前端攻城师想要 ...

  9. newton法分形图

    方程:z^6-1=0; %f为求解的方程,df是导数,使用的时候用funchandler定义 %res是目标分辨率,iter是循环次数,(xc,yc)是图像的中心,xoom是放大倍数 %参数视自己需求 ...

  10. 手动安装jar到maven

    mvn install:install-file -DgroupId=com.chinacloud.mir.common -DartifactId=one-aa-sdk -Dversion=1.0-S ...