【cocos2d-x 手游研发小技巧(6)聊天系统+字体高亮】
转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-6.html
聊天系统在手机网游中是最常见的交互工具,大家在一起边玩游戏边聊天岂不乐哉;
废话不多了,这里重点只介绍客户端的代码,首先输入框肯定用CCEditBox的了,现在这个最好用;
直接贴已经写好的代码:
首先是ChatInput.cpp这个类,主要就是弹出一个输入框,点击后弹出虚拟键盘输入完成后,点击发送的功能;
ChatInput.h
#include "cocos2d.h"
#include "cocos-ext.h"
#include "string"
using namespace std;
USING_NS_CC;
USING_NS_CC_EXT;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS||CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
class ChatInput : public CCLayer, public CCEditBoxDelegate
{
public:
ChatInput();
~ChatInput(); virtual bool init();
CREATE_FUNC(ChatInput); // 需要重写触摸注册函数,重新给定触摸级别
virtual void registerWithTouchDispatcher(void);
// 重写触摸函数,永远返回 true ,屏蔽其它层,达到 “模态” 效果
bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); // 构架,并设置对话框背景图片
static ChatInput* create(const char* backgroundImage); //添加输入框
void addEditBox(int tag);
void addEditBox(int tag,int maxlength);
//点击菜单按钮的回调
void buttonCallback(CCObject* pSender); // 为了在显示层时之前的属性生效,选择在 onEnter 里动态展示
virtual void onEnter();
virtual void onExit(); virtual void editBoxEditingDidBegin(cocos2d::extension::CCEditBox* editBox);
virtual void editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox);
virtual void editBoxTextChanged(cocos2d::extension::CCEditBox* editBox, const std::string& text);
virtual void editBoxReturn(cocos2d::extension::CCEditBox* editBox); // virtual void keyboardWillShow(cocos2d::CCIMEKeyboardNotificationInfo& info);
// virtual void keyboardDidShow(cocos2d::CCIMEKeyboardNotificationInfo& info);
// virtual void keyboardWillHide(cocos2d::CCIMEKeyboardNotificationInfo& info);
// virtual void keyboardDidHide(cocos2d::CCIMEKeyboardNotificationInfo& info); cocos2d::extension::CCEditBox* m_pEditName; void ShowChangeclass(CCObject *pSender);
void toChangeclass(CCObject *pSender); void sendMsg(CCObject *pSender);
private:
CCSize winSize;
void menuToggleCallback(CCObject* pSender); void togai(float togai); // 文字内容两边的空白区
int m_contentPadding;
int m_contentPaddingTop; CC_SYNTHESIZE_RETAIN(CCMenu*, m__pMenu, MenuButton);
CC_SYNTHESIZE_RETAIN(CCSprite*, m__sfBackGround, SpriteBackGround);
CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m__s9BackGround, Sprite9BackGround);
CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltTitle, LabelTitle);
CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltContentText, LabelContentText); CC_SYNTHESIZE_RETAIN(CCSprite*, m__sTitle, SpriteTitle); CC_SYNTHESIZE_RETAIN(CCEditBox*, m__pEditBox, EditBox); CCRect thisRect;//弹框的rect
CCRect getRect();
}; #endif
ChatInput.cpp
#include "ChatInput.h"
#include "../GameConfig.h"
#include "../Commen/PublicShowUI.h"
#include "../ImagePaths.h"
#include "../Commen/PublicDoFunc.h"
#include "../GameData/GlobalInfo.h"
#include "../ToDoCommen/ToDoSend.h" #if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS||CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
ChatInput::ChatInput()
:m__pMenu(NULL)
,m_contentPadding()
,m_contentPaddingTop()
,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 ();
return bRef; } void ChatInput::registerWithTouchDispatcher()
{
// 这里的触摸优先级设置为 -128 这保证了,屏蔽下方的触摸
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -, 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(, ), CCScale9Sprite::create(p_chat_input_bd));
if(maxlength>)
{
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(-,m_pEditBox->getContentSize().height/));
m_pEditBox->addChild(pMenu_button_chatclass,, BASEUI_CHAT_CLASS); setEditBox(m_pEditBox); //必须专门设置一次同layer级别一样的优先级,否则不能触发弹出键盘
getEditBox()->setTouchPriority();
} void ChatInput::sendMsg(CCObject *pSender)
{
string nrstr = GlobalInfo::getInstance()->get_chatnrstr();
if(nrstr.length()>)
{
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(""), CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create(""));
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(""), CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create(""));
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(""), CCString::create(nrstr.c_str()), CCString::create(roleinfo->Game_UserName), CCString::create(GlobalInfo::getInstance()->get_chatclassname().c_str()), CCString::create(""));
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/,button->getContentSize().height*1.45));
button->addChild(pMenu_button_qb,, 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/,button->getContentSize().height*2.4));
button->addChild(pMenu_button_sx,, 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/,button->getContentSize().height*3.4));
button->addChild(pMenu_button_tx,, 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/,button->getContentSize().height*4.4));
button->addChild(pMenu_button_jx,, 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,, 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,, 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,, 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,, 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(, ), CCScale9Sprite::create(p_chat_input_bd));
m_pEditBox->setMaxLength();
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/));
m_pEditBox->addChild(pMenu_button_chatclass,, 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/));
m_pEditBox->addChild(pMenu_button_send,, BASEUI_CHAT_SEND); setEditBox(m_pEditBox); m_pEditBox->schedule(schedule_selector(ChatInput::togai)); //必须专门设置一次同layer级别一样的优先级,否则不能触发弹出键盘
getEditBox()->setTouchPriority(-);
} 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()>)
{
// CCLog("size=%d",getMenuButton()->getChildrenCount());
float btnWidth = 100.0;
// CCLog("btnwidth=%f",btnWidth);
CCArray* array = getMenuButton()->getChildren();
CCObject* pObj = NULL;
int i = ;
CCARRAY_FOREACH(array, pObj)
{
CCNode* node = (CCNode*) pObj;
switch(i){
case :
// CCLog("btn width=%f",node->getContentSize().width);
node->setAnchorPoint(CCPointZero);
node->setPosition(ccp(getEditBox()->getPositionX()+getEditBox()->getContentSize().width + 2.0f , getEditBox()->getPositionY()));
break;
case :
node->setPosition(ccp(getEditBox()->getPositionX()+ , 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()!=NULL)
{
sp->removeChildByTag();
}
n_w=w;
n_h=h;
one_h=;
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,,);
} 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(, );
}
CCSize ChatTableView::tableCellSizeForIndex(CCTableView* table,unsigned int idx)
{
// CCLOG("size forindex==%d",idx);
if(idx < n_msglist.size()-)
{
idx += ;
}
Msgdata ms;
string chatnr = n_msglist.at(idx).MsgText;
string ss1s = chatnr; int higth=-;
if(chatnr.size()>)
{
higth=;
}
else
{
higth=;
}
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(), "", );
tf->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf->setColor(ccc3(, , ));
tf->setAnchorPoint(CCPointZero);
pcell->addChild(tf);
CCLabelTTF* tf2 = CCLabelTTF::create(playername.c_str(), "", );
tf2->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf2->setColor(ccc3(, , ));
tf2->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width/*1.1,tf->getContentSize().height/));
pcell->addChild(tf2); string st1,st2,st3;
if(chatnr.size()>)
{
st1 = chatnr.substr(,);
st2 = chatnr.substr(,chatnr.size());
CCLabelTTF* tf3 = CCLabelTTF::create(st1.c_str(), "", );
tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf3->setColor(ccc3(, , ));
tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
pcell->addChild(tf3);
if(st2.size()>)
{
CCLabelTTF* tf4 = CCLabelTTF::create(st2.c_str(), "", );
tf4->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf4->setColor(ccc3(, , ));
tf4->setPosition(ccp(tf->getPosition().x,tf->getPosition().y-tf4->getContentSize().height/*1.3));
pcell->addChild(tf4);
} }
else
{
CCLabelTTF* tf3 = CCLabelTTF::create(chatnr.c_str(), "", );
tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf3->setColor(ccc3(, , ));
tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
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 = -;
if(n_msglist.size()>)
{
count =n_msglist.size();
}
else
{
count = ;
}
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()-)
{
idx += ;
}int higth=-;
if(chatnr.size()>)
{
higth=;
}
else
{
higth=;
}
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(), "", );
tf->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf->setColor(ccc3(, , ));
tf->setAnchorPoint(CCPointZero);
pcell->addChild(tf);
CCLabelTTF* tf2 = CCLabelTTF::create(playername.c_str(), "", );
tf2->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf2->setColor(ccc3(, , ));
tf2->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width/*1.1,tf->getContentSize().height/));
pcell->addChild(tf2); string st1,st2,st3;
if(chatnr.size()>)
{
st1 = chatnr.substr(,);
st2 = chatnr.substr(,chatnr.size());
CCLabelTTF* tf3 = CCLabelTTF::create(st1.c_str(), "", );
tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf3->setColor(ccc3(, , ));
tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
pcell->addChild(tf3);
if(st2.size()>)
{
CCLabelTTF* tf4 = CCLabelTTF::create(st2.c_str(), "", );
tf4->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf4->setColor(ccc3(, , ));
tf4->setPosition(ccp(tf->getPosition().x,tf->getPosition().y-tf4->getContentSize().height/*1.3));
pcell->addChild(tf4);
} }
else
{
CCLabelTTF* tf3 = CCLabelTTF::create(chatnr.c_str(), "", );
tf3->setHorizontalAlignment(kCCTextAlignmentLeft); //对齐
tf3->setColor(ccc3(, , ));
tf3->setPosition(ccp(tf->getContentSize().width+tf2->getContentSize().width+tf3->getContentSize().width/,tf->getContentSize().height/));
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().length()>)
{
msgdatalist_qb = JsonPush::ToGetMsgListdata(strlist.at());
ChatTableView *tableview = new ChatTableView(this,this->getContentSize().width*0.9,this->getContentSize().height*0.9,msgdatalist_qb);
tableview->pTableView->setContentOffset(ccp(,this->getContentSize().height*0.05));
}
msgdatalist_qb.clear();
strlist.clear();
}
显示的时候注意要将最后一条聊天信息展示出来,用setContentOffset这个方法:
tableview->pTableView->setContentOffset(ccp(,this->getContentSize().height*0.05));
好了以上就是最核心部分,下面我贴图上我游戏里面的聊天效果:
下一篇我将介绍使用Lua做功能模块更新拓展的技巧文章;
—————————————————————————————————————————————————————————————
ps:仙凡奇缘官网 http://www.xianfancoco.com
cocos2dxQQ交流群:41131516
【cocos2d-x 手游研发小技巧(6)聊天系统+字体高亮】的更多相关文章
- 【cocos2d-x 手游研发小技巧(8)通讯的数据压缩与解压 】
今天说一下手机游戏通讯协议中的数据问题,大量的数据将给服务器端和客户端带来很大的压力,一般来说. 转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-8 ...
- 【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】
直插主题了,今天写了一下午,早就想要写这类似东西的,首先我不会选用CCLabelAtlas了,我直接用帧图片做. 首先我们要准备素材,我先把素材帖出来给大家: 这个是一张比较全的素材图,它包含了扣血的 ...
- 【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】
游戏开发中常遇到资源保护的问题. 目前游戏开发中常加密的文件类型有:图片,Lua文件,音频等文件,而其实加密也是一把双刃剑. 需要安全那就得耗费一定的资源去实现它.目前网上也有用TexturePack ...
- 【cocos2d-x 手游研发小技巧(5)获取网络图片缓存并展示】
今天是年前最后一天上班了,最后一天上班,祝大家马上有各种东西,最后一天也给写一点干货,就是获取网络图片: 经过自己简单封装了一下,实现了获取网络图片,按照比例展示出来,实现方法是cocos2dx - ...
- 【cocos2d-x 手游研发小技巧(4)与Android混编实现换“头像图片”】
cocos2dx在android平台上的游戏开发中往往会遇到一些混编需求,如: 比方有的社区类游戏需要用到更换玩家的“头像”操作,其实就是调用android servers服务里面的本地图片,以及选取 ...
- 【cocos2d-x 手游研发小技巧(3)Android界面分辨率适配方案】
先感叹一下吧~~android的各种分辨率各种适配虐我千百遍,每次新项目我依旧待它如初恋···· 每家公司都有自己项目工程适配的方案,这种东西就是没有最好,只有最适合!!! 这次新项目专项针对andr ...
- 【cocos2d-x 手游研发小技巧(2)循环无限滚动的登陆背景】
原创文章,转载请附上链接:http://www.cnblogs.com/zisou/p/cocos2d-xARPG6.html 首先让大家知道我们想要实现的最终效果是什么样的? 看一个<逆天仙魔 ...
- 【cocos2d-x 手游研发----目录】
感谢大家一直支持我写这样一系列的博客,从中我自己也获益良多,cocos2d-x这样一款非常棒的引擎,是值得我们去学习和分享的,谈到分享,那我就把这套写了差不多一两个月的框架给大家开源下载,写的很一般, ...
- 【cocos2d-x 手游研发----地图活起来了】
谈到地图不少人都说要做地图编辑器了,但是我暂时绕过这一步,如果不用寻路地图就不能移动?寻路就是会绕过障碍物的算法. 我做了一个简单的地图的思想,就是地图分层3层:背景层.可行区域层.遮罩层,但是地图就 ...
随机推荐
- css菜鸟学习之text-align属性,行内元素,块级元素居中详解
一.text-align属性 1.text-align用来设置元素中的的文本对齐方式,例如:如果需要设置图片的对齐方式,需要设置图片的父元素的text-align属性: 2.text-align只对文 ...
- Ugly number丑数2,超级丑数
[抄题]: [思维问题]: [一句话思路]:Long.valueOf(2)转换为long型再做 [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图 ...
- fragment 事务回滚 ---动态创建fragment
import java.util.Date; import java.util.LinkedList; import com.qianfeng.gp08_day23_fragment5.fragmen ...
- VC字符串处理整理
场景: 1.在存储数据时有时接口需要合并字符串值,并以某些特殊字符来合并部分,到需要的时候再分割它.如一些数值,人名等. 2.C++有strtok,stringstream和find函数来实现分割.可 ...
- ajax访问当前页面后的 [WebMethod]描述的方法
脚本: function show() { $.ajax({ type: "post", async: false, contentType: "application/ ...
- jetty 8.0 add filter example
http://zyn010101.iteye.com/blog/1679798 package com.cicc.gaf.sso.server;import java.io.IOException;i ...
- 洛谷 P2986 [USACO10MAR]伟大的奶牛聚集(树形动规)
题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...
- Debian use sudo
刚安装好的Debian默认还没有sudo功能.1.安装sudo# apt-get install sudo2.编辑 /etc/sudoers ,添加如下行# visudoroot ALL=(ALL:A ...
- TF Boys (TensorFlow Boys ) 养成记(二): TensorFlow 数据读取
TensorFlow 的 How-Tos,讲解了这么几点: 1. 变量:创建,初始化,保存,加载,共享: 2. TensorFlow 的可视化学习,(r0.12版本后,加入了Embedding Vis ...
- 20155233 2016-2017-2 《Java程序设计》第8周学习总结
20155233 2016-2017-2 <Java程序设计>第8周学习总结 学习目标 了解NIO 会使用Channel.Buffer与NIO2 会使用日志API.国际化 会使用正则表达式 ...