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

摘要:
需要对消息字符串进行拆分和解析,以正常提取消息中的文本和图片。

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

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

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

RichText使用方法:

【Lua】手游聊天系统客户端完成总结第1张【Lua】手游聊天系统客户端完成总结第2张
  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的数字

【Lua】手游聊天系统客户端完成总结第3张【Lua】手游聊天系统客户端完成总结第4张
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

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

【Lua】手游聊天系统客户端完成总结第5张【Lua】手游聊天系统客户端完成总结第6张
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

--判断是否是中文

【Lua】手游聊天系统客户端完成总结第7张【Lua】手游聊天系统客户端完成总结第8张
function cu:is_zh_ch(p)

    if p < 127 then

        return 0;

    else

        return 1;

    end

end
View Code

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

【Lua】手游聊天系统客户端完成总结第9张【Lua】手游聊天系统客户端完成总结第10张
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
");

        return "";

    end

end
View Code

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

【Lua】手游聊天系统客户端完成总结第11张【Lua】手游聊天系统客户端完成总结第12张
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】手游聊天系统客户端完成总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇流程梳理的重要性dos命令之telnet下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

浅析Lua中table的遍历

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://rangercyh.blog.51cto.com/1444712/1032925 当我在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: forke...

Delphi写DLL要注意的问题 (转)

今天写一个dll准备给.net调用, dll写出之后给用delphi测试一下, 居然出错, 更别说给.net调用了.查来查去原来是参数和返回值使用string类型, 后面看了'Delphi 编写 DLL 返回字符串,.net 调用。' 这篇文章才解决, 顺便也收藏了一下,原来delphi写的dll有这么多限制的.   这一点我们需要注意  a. 参数和返回...

国密算法Java代码的标准实现

   前一阵子做的项目,越来越多的金融类应用使用国密算法进行加解密的运算。     国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。     SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。     SM2为非对称加密,基于ECC。该算法已公开...

Dubbo封装rest服务返回结果

由于Dubbo服务考虑到一个是给其他系统通过RPC调用,另外一个是提供HTTP协议本身系统的后台管理页面,因此Dubbo返回参数在rest返回的时候配置拦截器进行处理。 在拦截器中,对返回参数封装成如下对象,并统一输出到前端。 1 packagecom.wjs.common.web; 2 3 importorg.apache.commons.lang....

Delphi的字符(Char),字符串(String),字符串指针(PChar),字符数组arrayofchar(来自http://delphi.cjcsoft.net/论坛)

Delphi有三种类型的字符: AnsiChar这是标准的1字节的ANSI字符,程序员都对它比较熟悉。 WideChar这是2字节的Unicode字符。 Char在目前相当于AnsiChar,但在Delphi 2010 以后版本中相当于WideChar. 记住因为一个字符在长度上并不表示一个字节,所以不能在应用程序中对字符长度进行硬编码, 而应该使用Siz...

python3 字符串base64编码

在一些项目中,接口的报文是通过base64加密传输的,所以在进行接口自动化时,需要对所传的参数进行base64编码,对拿到的响应报文进行解码; str(源字符串)--str(加密后)--str(解密) Python 2 将 strings 处理为原生的 bytes 类型,而不是 unicode, Python 3 所有的 strings 均是 unico...