在写聊天系统的时候遇到几个问题,在这里记录一下,防止以后忘记。
1.在聊天系统中,有一个功能很常见,就是点击聊天层以外的地方,聊天层自动影藏,在C++里面或许很简单,但是在lua里面方法也很多,基本和c++一样,但就是语法不会,在这里记一下:
local function touchCallback(event)
local eventType = event.name;
if eventType == "began" then
print("触摸开始")
return true;
elseif eventType == "moved" then
print("触摸移动")
elseif eventType == "ended" then
print("触摸结束")
--self:removeFromParent();
self:remove()
end
end
self:onTouch(touchCallback,0, false);
在这里的self就是聊天层,我的聊天层继承的是cc.Layer
2.按钮的状态机的实现,在c++里面或许简单在,在这里也就记一下语法:
self.Button_chat:addClickEventListener(handler(self, self.onClickCallBack_send));
在这里self.Button_chat就是一个简单的按钮,onClickCallBack是一个回调函数
function GameChatLayer:onClickCallBack_send(sender,eventType)
Local name = sender:getName()
if eventType == ccui.ListViewEventType.ONSELECTEDITEM_END then
--在这里添加你想要的代码
end
End
这样你可以通过回去按钮的标签值或者名字来分别不同的按钮
3.listview的使用
如何往listview中添加item:
创建一个图片,给图片上添加你想要的东西,要设置大小,可触摸,如果后面你需要找出来,那就还要设置标签,最后加到listview里面作为一个item,代码demo如下:
local str = { "隔壁都听牌了,我怎么还不自摸",
"不好意思我又自摸了",
"曾经有首歌,上碰下自摸",
"人生不是彩排,请小心出牌",
"一直被模仿,从未被超越",
"快点放炮,从头来过",
"什么网络,你怎么又断线了",
"你的牌打得太精彩了,给你点赞",
"我有事,先走一步,大家尽兴慢慢玩",
"又胡了~来宾,掌声鼓励!",
"长夜漫漫,无心睡眠,玩通宵吧",
"别磨叽,快点出牌!",
"你家里是开银行的吧",
"你放炮我不胡"
};
--常用语列表背景图
local listItem = ccui.ImageView:create("Games/landlord/game/studioUI/uiRes/chatRes/list.png");
local itemWidth = listItem:getContentSize().width;
local itemHeight = listItem:getContentSize().height;
listItem:setName("listItem");
listItem:setTouchEnabled(true);
--文字
local commonText = ccui.Text:create("","",22);
commonText:setColor(cc.c3b(128,128,128));
commonText:setAnchorPoint(0,0.5);
commonText:setName("commonText")
print("常用语层位置:"..itemWidth..","..itemHeight)
commonText:setPosition(cc.p(itemWidth*0.1,itemHeight*0.55));
commonText:setString(GBKToUtf8(str[idx]));
--commontext:setName("commonText")
commonText:setTag(1000+idx);
listItem:addChild(commonText);
self.ListView_common:pushBackCustomItem(listItem);--添加
如何给listview添加回调,让我们在点击listview里面的子空间item是知道我们点击的对象是谁?
首先添加监听
self.ListView_common:addEventListener(handler(self, self.onClickCallBack_list))--给listview添加监听
会调函数是可以有参数的,你可以获取到你点击的item,不过这里有一个坑需要注意:
就是我们点击完item之后如果想要立马移除聊天层的话会报错,至于这个报错的原因我不知道,经过探索之后才发现只要加一个延时就可以解决了。
local action1 = cc.DelayTime:create(0.1);
local action2 = cc.CallFunc:create(function() self:removeFromParent(); end);
self:runAction(cc.Sequence:create(action1, action2));--要注意这里一个坑
4.lua中字符串处理需要注意:
在lua中数字和字母是占用一个字节长度的,汉字是占用3个字节长度的,通过
string.sub()函数你可以获取到每一个字节的内容,string.byte()函数可以获得到这个字节的ascii值,大于127的基本可以判断为汉字了。
后面不多说附上代码:
local GameChatLayer = class("GameChatLayer", function() return display.newLayer(); end)
local TableLogic = require("game.game.TableLogic");
function GameChatLayer:create(tableLogic)
return GameChatLayer.new(tableLogic);
end
function GameChatLayer:ctor(tableLogic)
self.tableLogic = tableLogic
self.widget = nil--这个聊天面板
local panel = cc.CSLoader:createNode("csbs/GameChatUi.csb");
self:addChild(panel);
self.widget = panel:getChildByName("Panel_Chat")
self.Image_chatGB = nil--背景
self.ScrollView_face = nil--表情列表
self.ListView_common = nil--常用语列表
self.ListView_chatRecord = nil --历史记录
self.Button_common = nil--常用语按钮
self.Button_face = nil--笑脸按钮
self.Button_chat= nil--历史记录按钮
self.Button_send= nil--发送按钮
self.TextField_msg= nil--输入框
self.faceList = {}--68个表情按钮
self.chatList = {}--14个常用语按钮
self:initUI()
self:setTouchListener();--添加触摸监听
--小图路径--给按钮什么的添加回调函数
self:setButtonCallBack();
-- --聊天记录
-- self.chatTextArray = {
-- "/:00隔壁都听牌了,我怎么还不自摸"
-- }
--self:onTouch(touchCallback,0, true);
--self:addChatRecord(self.chatTextArray)
end
function GameChatLayer:initUI()
--self.Button_/:00:setVisible(true)
self.Image_chatBG = self.widget:getChildByName("Image_chatBG");
self.ScrollView_face = self.Image_chatBG:getChildByName("ScrollView_face")--笑脸
self.ScrollView_face:setName("ScrollView_face")
--self.ScrollView_face:setVisible(false)
self.ListView_common = self.Image_chatBG:getChildByName("ListView_common")--常用语
self.ListView_common:setName("ListView_common")
self.ListView_chatRecord = self.Image_chatBG:getChildByName("ListView_chatRecord")--历史记录
self.ListView_chatRecord:setName("ListView_chatRecord")
self.Button_common = self.Image_chatBG:getChildByName("Button_common")--常用语按钮
self.Button_common:setName("Button_common")
self.Button_face = self.Image_chatBG:getChildByName("Button_face")--笑脸按钮
self.Button_face:setName("Button_face")
self.Button_chat= self.Image_chatBG:getChildByName("Button_chat")--历史记录按钮
self.Button_chat:setName("Button_chat")
self.Button_send= self.Image_chatBG:getChildByName("Button_send")--发送按钮
self.Button_send:setName("Button_send")
-- self.TextField_msg= self.Image_chatBG:getChildByName("TextField_msg")--输入框
-- self.TextField_msg:setName("TextField_msg")
-- self.TextField_msg:setString(" ")
--local editBoxSize = cc.size(120,20)
self.TextField_msg = ccui.EditBox:create(cc.size(360,40),"game/table/kuang.png")
self.TextField_msg:setPosition(self.Image_chatBG:getChildByName("TextField_msg"):getPosition())
self:addChild(self.TextField_msg)
self.TextField_msg:setColor(cc.c3b(255,255,250))
--self.TextField_msg = edit
self.TextField_msg:setMaxLength(32)
--local face = self.ScrollView_face:getChildByName("/:00")
--创建常用语
for i=1,14 do
self:createCommonList(i)
end
for i=1,68 do
local str = nil
if i<=10 then
str = "/:0"..i-1
else
str = "/:"..i-1
end
--print("查找笑脸名字"..str)
self.faceList[i] = self.ScrollView_face:getChildByName(str)
--self.faceList[i]:setColor(cc.c3b(255,255,0))
end
end
--触摸监听
function GameChatLayer:setTouchListener()
local function touchCallback(event)
local eventType = event.name;
if eventType == "began" then
print("触摸开始")
return true;
elseif eventType == "moved" then
print("触摸移动")
elseif eventType == "ended" then
print("触摸结束")
--self:removeFromParent();
self:remove()
end
end
self:onTouch(touchCallback,0, false);
end
function GameChatLayer:remove()
-- body
self:removeFromParent();
end
function GameChatLayer:createCommonList(idx)
local str = { "隔壁都听牌了,我怎么还不自摸",
"不好意思我又自摸了",
"曾经有首歌,上碰下自摸",
"人生不是彩排,请小心出牌",
"一直被模仿,从未被超越",
"快点放炮,从头来过",
"什么网络,你怎么又断线了",
"你的牌打得太精彩了,给你点赞",
"我有事,先走一步,大家尽兴慢慢玩",
"又胡了~来宾,掌声鼓励!",
"长夜漫漫,无心睡眠,玩通宵吧",
"别磨叽,快点出牌!",
"你家里是开银行的吧",
"你放炮我不胡"
};
--常用语列表背景图
local listItem = ccui.ImageView:create("Games/landlord/game/studioUI/uiRes/chatRes/list.png");
local itemWidth = listItem:getContentSize().width;
local itemHeight = listItem:getContentSize().height;
listItem:setName("listItem");
listItem:setTouchEnabled(true);
--文字
local commonText = ccui.Text:create("","",22);
commonText:setColor(cc.c3b(128,128,128));
commonText:setAnchorPoint(0,0.5);
commonText:setName("commonText")
print("常用语层位置:"..itemWidth..","..itemHeight)
commonText:setPosition(cc.p(itemWidth*0.1,itemHeight*0.55));
commonText:setString(GBKToUtf8(str[idx]));
--commontext:setName("commonText")
commonText:setTag(1000+idx);
listItem:addChild(commonText);
self.ListView_common:pushBackCustomItem(listItem);
end
--添加回调
function GameChatLayer:setButtonCallBack()
if self.Button_common then
--self.Button_common:addTouchEventListener(function() self:onClickCallBack_common(sender,eventType) end)
self.Button_common:addClickEventListener(handler(self, self.onClickCallBack_common));
--self.Button_common:setVisible(false)
end
if self.Button_face then
self.Button_face:addClickEventListener(handler(self, self.onClickCallBack_common));
end
if self.Button_chat then
self.Button_chat:addClickEventListener(handler(self, self.onClickCallBack_common));
end
if self.Button_send then
self.Button_send:addClickEventListener(handler(self, self.onClickCallBack_send));
end
--表情
for i=1,68 do
--self.faceList[i]:addTouchEventListener(hander(self,function() self:onFace(sender) end));
self.faceList[i]:addClickEventListener(handler(self, self.onFace));
end
self.ListView_common:addEventListener(handler(self, self.onClickCallBack_list))--给listview添加监听
end
function GameChatLayer:onFace(sender)
print("点击笑脸了")
local name = sender:getName()
print(name)
local str = self.TextField_msg:getText()
str = str .. name
self.TextField_msg:setText(str)
self.tableLogic:sendChatMsg(0,self.TextField_msg:getText())
self:removeFromParent()
end
function GameChatLayer:onClickCallBack_list(sender,eventType)
print("eventType="..eventType.."ccui.ListViewEventType.ONSELECTEDITEM_END="..ccui.ListViewEventType.ONSELECTEDITEM_END)
if eventType == ccui.ListViewEventType.ONSELECTEDITEM_END then
print("常用语回调函数,sender"..sender:getCurSelectedIndex())
local listItems = sender:getItem(sender:getCurSelectedIndex())
local commontext = listItems:getChildByName("commonText")
local nIndex = commontext:getTag()-1000;
print("nIndex"..nIndex)
local action1 = cc.DelayTime:create(0.1);
local action2 = cc.CallFunc:create(function() self:removeFromParent(); end);
self:runAction(cc.Sequence:create(action1, action2));--要注意这里一个坑
print(nIndex,commontext:getString())
self.tableLogic:sendChatMsg(nIndex,commontext:getString())
end
end
--按钮回调函数
function GameChatLayer:onClickCallBack_common(sender,eventType)
-- body
--print("进入聊天类按钮回调函数,sender = "..sender.."eventType"..eventType.."ccui.TouchEventType.ended"..ccui.TouchEventType.ended)
-- if eventType ~= ccui.TouchEventType.ended then
-- return
-- end
local name = sender:getName();
print(name)
--常用语
if name ~= "Button_common" then
print("常用语")
self.Button_common:setHighlighted(false)
self.Button_common:setLocalZOrder(100)
end
--笑脸
if name ~= "Button_face" then
print("笑脸")
self.Button_face:setHighlighted(false)
self.Button_common:setLocalZOrder(99)
end
--历史记录
if name ~= "Button_chat" then
print("历史记录")
self.Button_chat:setHighlighted(false)
self.Button_common:setLocalZOrder(99)
end
if name == "Button_common" then
self.ListView_common:setVisible(true)
self.ScrollView_face:setVisible(false)
self.ListView_chatRecord:setVisible(false)
end
if name == "Button_face" then
self.ListView_common:setVisible(false)
self.ScrollView_face:setVisible(true)
self.ListView_chatRecord:setVisible(false)
end
if name == "Button_chat" then
self.ListView_common:setVisible(false)
self.ScrollView_face:setVisible(false)
self.ListView_chatRecord:setVisible(true)
end
end
function GameChatLayer:onClickCallBack_send()
print("发送按钮回调")
--发送
print("发送")
self.Button_send:setHighlighted(false)
self.Button_common:setLocalZOrder(100)
if self.TextField_msg:getText() == nil then
--提示弹框("输入框不能为空")
else
--这里回调成功接口函数
print("发送聊天消息了,聊天内容:"..self.TextField_msg:getText())
self.tableLogic:sendChatMsg(0,self.TextField_msg:getText())
self:removeFromParent();
end
end
function GameChatLayer:addChatRecord(msg)
local str = msg
--小图路径
local filenameSmallImage = "Games/landlord/game/studioUI/uiRes/chatSmallRes/"
local maxFaceCount = 68;
local word = nil;
local num = {0,0,0}
local lineSize = cc.size(540, 30)
local fontSize = 15;
local imageSize = 24;
local msgAllLenght = 0;
local ImageNum = 0;
local msgNumber = 0;
local n = #str
print("n = "..n)
for i=1,n do
-- local listItem = ccui.ImageView:create("Games/landlord/game/studioUI/uiRes/chatRes/list.png");
-- local itemWidth = listItem:getContentSize().width;
-- local itemHeight = listItem:getContentSize().height;
-- --查找表情符号
-- self:foundFace(str[i])
-- -- print(have)
-- -- --文字
-- local commonText = ccui.Text:create("","",16);
-- commonText:setColor(cc.c3b(128,128,128));
-- commonText:setAnchorPoint(0,0.5);
-- commonText:setPosition(itemWidth*0.1,itemHeight*0.55);
-- commonText:setString(GBKToUtf8(str[i]));
-- listItem:addChild(commonText);
-- self.ListView_chatRecord:pushBackCustomItem(listItem);
local charMsg = ccui.RichText:create()
charMsg:setAnchorPoint(0.5,1)
charMsg:setContentSize(cc.size(520,30))
charMsg:ignoreContentAdaptWithSize(false)
--for j = 1,#str[i] do
-- local j = 1
-- if string.sub(str[i],j,j) then print("true") else print("false") end
-- while(j<#str[i]) do --string.sub(str[i],j,j)
-- local s = str[i]
-- print("找表情"..#str[i]..string.sub(str[i],j,j)..j)
-- if string.sub(str[i],j,j) == "/" and string.sub(str[i],j+1,j+1) then
-- ----一定是表情
-- print("找到/:")
-- if string.byte(string.sub(str[i],j+2,j+2))>47 and string.byte(string.sub(str[i],j+2,j+2))<54 and string.byte(string.sub(str[i],j+3,j+3))>47 and string.byte(string.sub(str[i],j+3,j+3))<56 then
-- if word then
-- local rText = RichElementText:create(0,cc.c3b(128,128,128),255,word,"Arial", fontSize)
-- charMsg:pushBackElement(rtext)
-- word = nil
-- end
-- ImageNum = ImageNum +1
-- local imageNumber = string.sub(str[i],j+2,j+2)..string.sub(str[i],j+3,j+3)
-- print("拼出来的数字是:"..imageNumber)
-- local imageStr = filenameSmallImage.."im"..imageNumber..".png"
-- print(imageStr)
-- local img = ccui.RichElementImage:create( 6, cc.c3b(255, 255, 255), 255, imageStr )
-- charMsg:pushBackElement(img);
-- j = j+3;
-- else--不是表情
-- msgAllLenght = msgAllLenght + 0.5
-- if word then word = word..str[i][j]
-- else word = str[i][j] end
-- end
-- else
-- msgAllLenght = msgAllLenght + 0.5
-- if string.byte(string.sub(str[i],j,j)) > 127 then
-- if word then
-- word = word..string.sub(str[i],j,j+2)
-- else
-- word = string.sub(str[i],j,j+2)
-- end
-- print("找到汉字了:"..word)
-- j=j+2
-- else
-- if word then
-- word = word..string.sub(str[i],j,j)
-- print("不空") print(word)
-- else
-- word = str[i][j]
-- print("空"..string.sub(str[i],j,j))
-- print(word)
-- end
-- end
-- end
-- j = j+1
-- end
local isFace = false;
local FaceStr = nil;
local m_num = 0;--记录查询次数
local nameStr = nil;--记录名字
for m = 1,#str[i] do
--找到名字分割符
--print(string.sub(str[i],m,m))
if string.sub(str[i],m,m) == "]" and string.sub(str[i],m+1,m+1) == ":" then
nameStr = string.sub(str[i],1,m+1)--找到名字
print("找到分割符,找到名字:",nameStr)
m_num = m_num +1;
if string.sub(str[i],m+2,m+2) == "/" and string.sub(str[i],m+3,m+3) == ":" then
if string.byte(string.sub(str[i],m+4,m+4))>47 and string.byte(string.sub(str[i],m+4,m+4))<55 and string.byte(string.sub(str[i],m+5,m+5))>47 then
isFace = true;--一定是笑脸
if string.sub(str[i],m+4,m+4) ~= "0" then
FaceStr = string.sub(str[i],m+4,m+4)..string.sub(str[i],m+5,m+5)
else
FaceStr = string.sub(str[i],m+5,m+5)
end
print("找到笑脸")
end
end
end
end
--显示文本
--if word then
-- print("创建富文本")
-- local text = ccui.RichElementText:create(0, cc.c3b(128,128,128), 255, GBKToUtf8("啊哈哈"), "Arial", fontSize);
-- charMsg:pushBackElement(text)
-- --self.ListView_chatRecord:addChild(text)
-- word = ""
--end
-- local img = ccui.RichElementImage:create( 6, cc.c3b(255, 255, 255), 255, "Games/landlord/game/studioUI/uiRes/chatSmallRes/im0.png" )
-- charMsg:pushBackElement(img);
local realAllLenght = msgAllLenght * fontSize + ImageNum * imageSize;--文本图片总的真实大小
local msgRowNum = realAllLenght / 520
local msgHeight = 0;
if msgRowNum < 1 then
msgHeight = lineSize.height;
else
msgHeight = lineSize.height + (20*msgRowNum)
end
--聊天消息子项
local msgLayout = ccui.ImageView:create("Games/landlord/game/studioUI/uiRes/list.png")
msgLayout:setContentSize(550,45)
msgLayout:setColor(cc.c3b(51,42,93))
print("lineSize:"..lineSize.width.."/"..msgHeight)
--msgLayout:setContentSize(cc.size(lineSize.width,msgHeight))
msgLayout:setAnchorPoint(0,0)
msgLayout:addChild(charMsg)
print("添加聊天回看记录了————————————————————————————————————————————————————")
--文字
local p = ccui.Text:create("","",15)
p:setAnchorPoint(0,0)
p:setString(str[i])
--在这里判断文字是不是太长,如果太长的话那么就需要把宽度加宽
if self:getWidth(str[i])>20 then
p:ignoreContentAdaptWithSize(false)
p:setSize(400,30)
end
p:setPosition(cc.p(0,0))
p:setColor(cc.c3b(0,0,0))
msgLayout:addChild(p)
--图片
if isFace then
print("有表情,表情的数字标签号是:",FaceStr)
local s = ccui.ImageView:create("Games/landlord/game/studioUI/uiRes/chatSmallRes/im"..FaceStr..".png" )
s:setAnchorPoint(0,0)
local posX = self:getWidth(nameStr) * 20
s:setPosition(cc.p(posX,0))
msgLayout:addChild(s)
p:setString(nameStr)
end
print(msgLayout:getContentSize().width.."--"..msgLayout:getContentSize().height)
--charMsg:setPosition(msgLayout:getContentSize().width*0.5+10,msgLayout:getContentSize().height)
charMsg:setPosition(0,0)
self.ListView_chatRecord:pushBackCustomItem(msgLayout)
ImageNum = 0
msgAllLenght = 0
end
end
function GameChatLayer:foundFace(str)
-- body
local face = {}
local n = #str;
print("长度"..n)
local i = 1;
-- for i =1,n do
-- if string.byte(str[i]) == 47 and string.byte(str[i+1]) == 58 then
-- print("/:")
-- if str[i+2].tonumber() > -1 and str[i+2]<6 then
-- print("3")
-- if str[i+3].tonumber() > -1 and str[i+3]< 8 then
-- table.insert(i)
-- print("有啦")
-- end
-- end
-- end
-- end
local have = string.find(str,"/:")
if have ~= nil then
print("找到"..have)
end
end
function GameChatLayer:getWidth(msg)
-- body
local num = 0;--表示占用多少位长度
--笑脸
if #msg == 4 then
if string.sub(msg,1,1) == "/" and string.sub(msg,2,2) == ":" then
if string.byte(string.sub(msg,3,3))>47 and string.byte(string.sub(msg,3,3))<54 and string.byte(string.sub(msg,4,4))>47 then
num = 4
return num
end
end
end
--字符串
local i = 1
print("获得长度:",#msg,msg)
while (i<=#msg) do
--todo
if string.byte(string.sub(msg,i,i))>127 then
--说明找到一个汉字
num = num +1
i = i +2
else
num = num + 0.5
end
i = i+1
end
if num<4 then num = 4 end
return num;
end
return GameChatLayer