【Lua】手游聊天系统客户端完成总结

 

网上很多例子,我是参考这篇文章:http://www.myexception.cn/operating-system/1591495.html

 

1.聊天系统难题一:消息需要支持插入表情和换行。

一开始我打算借鉴上面文章中的方法自己用label和image拼接实现自己的富文本,后来同事建议我使用cocos2dx自带的富文本空间RichText,网上找了一些例子学习,在代码中使用发现效果还不错,可以插入图片,也支持自动换行(通过setContentSize(cc.size(width,height))来设置空间的宽高之后,超过宽度的内容就可以自动换行)

RichText使用方法:

  local rt = ccui.RichText:create();



  rt:ignoreContentAdaptWithSize(false);



  rt:setContentSize(cc.size(550,120));



  --第一个参数是Tag



  local re1 = ccui.RichElementText:create(1,cc.c3b(255, 255,255), 255,"地瓜与土豆的小清新","Marker Felt",24);  --文本



    local re2 = ccui.RichElementImage:create(3,cc.c3b(255, 255, 255), 255, "equip/test_icon.png");  --图片



    local sp = cc.Sprite:create("equip/test_icon1.png");



  local re3 = ccui.RichElementCustomNode:create(4,cc.c3b(255,255,255),255,sp);  --自定义



  rt:pushBackElement(re1);



  rt:pushBackElement(re2);



  rt:pushBackElement(re2);



  --最后把rt加入到容器中,这里我使用的是listview



  list:pushBackCustomItem(rt);
View Code

 

2.聊天系统难题二:对消息的格式化处理。

需要对消息字符串进行拆分解析,才能正常提取出消息中的文字和图片。

下面是几个我使用到的字符串处理函数:

 

--判断字符是否为0到9的数字

function cu:is_number(char) --这里传入的char是通过函数string.byte(字符串,下标)取出的对应字符的整数形式





    if char >= 48 and char <= 57 then





        print("char==number:"..str);





        return true;





    end





    return false;





end
View Code

--获取字符串的真实长度处理

function cu:getRealStringLength(str)



    local i = 1;



    local len = string.len(str);



    local r = 0;



    while i<=len do



        if (self:is_zh_ch(string.byte(str, i))==1) then  --这里使用了is_zh_ch()判断是否为中文



            r=r+1;



            i=i+3;



        else



            r=r+1;



            i=i+1;



        end



    end



    return r;



end
View Code

--判断是否是中文

function cu:is_zh_ch(p)



    if p < 127 then



        return 0;



    else



        return 1;



    end



end
View Code

--截取字符,避免乱码的处理;

function cu:subString(str,start,ends)



    if string.len(str)>0  then



    



        local len = string.len(str);



        local tmp = "";



        



        --先把str里的汉字和英文分开



        local dump = {};



        local i = 1;



        while i<=len do



            if (cu:is_zh_ch(string.byte(str, i))==1) then



                table.insert(dump,table.getn(dump)+1,string.sub(str,i,i+2));



                i=i+3;



            else



                table.insert(dump,table.getn(dump)+1,string.sub(str,i,i));



                i=i+1;



            end



        end



        



        local iDumpSize = table.getn(dump);



        if ends > 0 then



        ends = ends;



        else



            ends = iDumpSize;



        end



      



        if(start<0 or start>ends) then



            return "";



         end



         



        for i = start, ends, 1 do  



            if dump[i]~=nil then



                tmp = tmp..dump[i];



            end    



        end



      



        return tmp;



    else



        print("str is not string\n");



        return "";



    end



end
View Code

--解析消息字符串,将解析后的内容放入RichText返回

function cu:changeToRichText(str)



    local richtext_ = ccui.RichText:create();



    richtext_:ignoreContentAdaptWithSize(false);



    if cu:getRealStringLength(str) > 25 then



        richtext_:setContentSize(cc.size(500,60));



    else



        richtext_:setContentSize(cc.size(500,30));



    end



    



    local iMsgEnd = 1;



    local iMsgStart = 1;



    local r = "";



    local iRealLength = cu:getRealStringLength(str);



    local continue = false;



    



    while (cu:subString(str,iMsgStart,iMsgEnd) ~= "") do



        r = cu:subString(str,iMsgStart,iMsgEnd);



        continue = false;



        --先判断当前读取的字符内容是否是表情



        if(string.sub(r,string.len(r),string.len(r))=='[') then



            print("有表情");



            local tmp = cu:subString(str,iMsgEnd,iMsgEnd+3);



            print("string.sub(tmp,2,2):"..string.sub(tmp,2,2));



            print("string.sub(tmp,3,3):"..string.sub(tmp,3,3));



            print("string.sub(tmp,4,4):"..string.sub(tmp,4,4));



     



            if(string.sub(tmp,4,4)==']' and cu:is_number(string.byte(tmp,2)) and cu:is_number(string.byte(tmp,3))) then --face



                --表情前面若有内容的处理



                print("有表情1");



                if(iMsgEnd-iMsgStart>0) then



--                    textView->setString(r.substr(0,r.length()-1).c_str());



                    local txt_1 = string.sub(r,1,string.len(r)-1);



                    local temp_re_txt = ccui.RichElementText:create(1,cc.c3b(255, 255,255), 255,txt_1,"Marker Felt",24);



                    richtext_:pushBackElement(temp_re_txt);



                    print("字符串1:"..txt_1); 



                end



    



                --如果有表情的处理



                local temp = {0};



                if(string.sub(tmp,2,2)-'0' == 0) then



                    temp = "equip/test_icon"..(string.sub(tmp,3,3)-'0')..".png";



                else



                    temp = "equip/test_icon"..(string.sub(tmp,2,2)-'0')..(string.sub(tmp,3,3)-'0')..".png";



                end



                



                local temp_re_image = ccui.RichElementImage:create(2,cc.c3b(255, 255, 255), 255, "equip/test_icon.png");



--                local temp_re_image = ccui.RichElementImage:create(2,cc.c3b(255, 255, 255), 255, temp);



                richtext_:pushBackElement(temp_re_image);



                



                iMsgEnd = iMsgEnd + 4;



                iMsgStart = iMsgEnd;



                



                if(iMsgEnd>iRealLength) then



                    break;



                end



--                goto next  



                continue = true;



           end



        end    



--        local txt_2 = r; 



        if not continue then



            if(iMsgEnd>=iRealLength) then



                break;



            end



            iMsgEnd = iMsgEnd+1; 



        end



--        iMsgStart=iMsgEnd;



          



--        ::next::



     end 



    local txt_2  = cu:subString(str,iMsgStart,iMsgEnd);



    local temp_re_txt = ccui.RichElementText:create(1,cc.c3b(255, 255,255), 255,txt_2,"Marker Felt",24);



    richtext_:pushBackElement(temp_re_txt);



    print("字符串2:"..txt_2);



    



    return richtext_;



end
View Code

tip:对哪种格式的文本是图片完全根据个人喜好制定,不好用常用的聊天符号就行,这里我使用的是[xx](x为0~9的数字)

 

3.聊天系统难题三:控制发送消息的时间间隔。

需要使用定时器:

  --定时器控制发送消息的频率 (参数1是定时器函数 参数2是定时器的循环时间间隔 参数3表示是否循环)

  self.ScriptFuncId = CCDirector:sharedDirector():getScheduler():scheduleScriptFunc(self.send_message_scheduler,send_time_interval,false);

  --控制发送消息频率定时器函数

  function cu:send_message_scheduler()

      if_send = true; --在定时器中把标记设置为真,每次发送消息后将标记重新设置回false,通过此标记控制是否可以发送消息

  end

 

 

你可能感兴趣的:(lua)