zoukankan      html  css  js  c++  java
  • 【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
    ");
    
            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

     

     

  • 相关阅读:
    面向对象之三个基本特征(javaScript)
    webpack初探
    浅谈Promise
    Vue Mixin 与微信小程序 Mixins 应用
    C#入门基础语法知识点总结(变量、运算符、类型转换)
    C#入门基础语法知识点总结(.NET开发环境及代码编写规范)
    触发器练习三
    触发器练习二
    触发器练习一
    存储过程练习二
  • 原文地址:https://www.cnblogs.com/Liyang1992/p/4015799.html
Copyright © 2011-2022 走看看