聊天系统实战记录

在写聊天系统的时候遇到几个问题,在这里记录一下,防止以后忘记。

 

 

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

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值