zoukankan      html  css  js  c++  java
  • 页游聊天模块图文混排解决方案

    找了很长时间的聊天模块添加表情的解决方案。综合比较一下,最终选择闪刀浪子的TalkField。

    选择它的理由:代码量小,简单易懂,使用方便。可以满足项目需求。

    网上提供的其它几种方案,如果不能够熟知其原理,项目出什么问题了,维护起来时比较麻烦的。

    预览:

    主文档代码:

    package
    {
        import flash.display.Loader;
        import flash.display.LoaderInfo;
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.events.TextEvent;
        import flash.net.URLRequest;
        import flash.system.ApplicationDomain;
        
        public class Main extends Sprite
        {
            private var _loader:Loader;
            private var _outputText:TalkField;
            private var _inputText:TalkField;
            private var _sendBtn:Button;//发送按钮
            private var _faceBar:MovieClip;
            private var _app:ApplicationDomain;
            
            [Embed(source="face.swf",mimeType="application/octet-stream")]
            public var swfClass:Class;
            
            public function Main()
            {
                _loader = new Loader();
                _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
                //_loader.load(new URLRequest('face.swf'));
                _loader.loadBytes(new swfClass());
                
            }
            
            private function onComplete(evt:Event):void
            {
                _app = (evt.currentTarget as LoaderInfo).applicationDomain;
                var _faceBarClass:Class = _app.getDefinition('faceBar') as Class;
                _faceBar = new _faceBarClass();
                
                initText();
            }
            
            private function initText():void
            {
                _outputText = new TalkField(300,200,_app);
                _outputText.tf.selectable = false;
                this.addChild(_outputText);
                _outputText.x = stage.stageWidth-_outputText.width >> 1;
                _outputText.y = 30;
                _outputText.tf.addEventListener(TextEvent.LINK,onLink);
                
                _inputText = new TalkField(300,26,_app,'input');
                this.addChild(_inputText);
                _inputText.x = stage.stageWidth-_inputText.width >> 1;
                _inputText.y = 280;
                _inputText.setText('输入聊天信息');
                _inputText.tf.restrict = '^/[\u3000]/g';//限制不许输入全角空格
                
                this.addChild(_faceBar);
                _faceBar.x = 220;
                _faceBar.y = _inputText.y - 30;
                _faceBar.addEventListener(MouseEvent.CLICK,onBarClick);
                
                _sendBtn = new Button('发送');
                this.addChild(_sendBtn);
                _sendBtn.x = _inputText.x + _inputText.width + 5;
                _sendBtn.y = _inputText.y;
                _sendBtn.addEventListener(MouseEvent.CLICK,sendMsg);
                
            }
            
            private function onBarClick(evt:MouseEvent):void
            {
                var str:String = evt.target.name.replace(/f/g,'/');
                _inputText.tf.appendText(str);
            }
            
            private function onLink(evt:TextEvent):void
            {
                _inputText.setText(evt.text);
                
            }
            
            private var arr:Array = new Array();
            private function sendMsg(event:MouseEvent):void
            {
                arr.push("/07<a href='event:这是我的姓名'><u>[鬼精灵]</u></a>说:" + _inputText.tf.text + '<br />');
                _outputText.setMultiText(arr);
                _inputText.tf.text = '';
            }
        }
    }

    闪刀浪子开源类TalkField:

    package
    {
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.filters.GlowFilter;
        import flash.geom.Rectangle;
        import flash.system.ApplicationDomain;
        import flash.text.TextField;
        import flash.text.TextFieldType;
        import flash.text.TextFormat;
        
        /**
         * 图文显示框
         * @author 闪刀浪子
         * 使用方法:
         */
        public class TalkField extends Sprite
        {
            private var _tf:TextField;
            private var _type:String;
            private var _tfMask:Sprite;
            private var _faceContainer:Sprite;
            
            private var _maskWidth:Number;
            private var _maskHeight:Number;
            
            private var _textFormat:TextFormat;
            private var _leading:Number
            private var _textColor:uint;
            
            private var _appDomain:ApplicationDomain;
            
            /**
             * 构造函数
             * @param    width    图文宽度
             * @param    height  图文框高度
             * @param    leading  显示的文本行的行间距
             * @param    appDomain  包含"facexx"的程序域
             * @param    textColor    默认文本的颜色,如果没有用<font>标签定义颜色,则使用此颜色
             * @param    alpha  图文框的背景透明度
             */
            public function TalkField(Number, height:Number, 
                                      appDomain:ApplicationDomain = null,textType:String = 'dynamic',
                                        leading:Number=2,textColor:uint=0xffffff) 
            {
                trace(TextFieldType.DYNAMIC);
                _maskWidth = width;
                _maskHeight = height;
                _leading = leading;
                _textColor = textColor
                _type = textType;
                _appDomain = appDomain==null?ApplicationDomain.currentDomain:appDomain;
                
                initView()
                initEvent();
            }
            
            private function initView():void
            {
                createBK();
                createMask();
                createTF();
                createFaceContainer();
            }
            
            private function initEvent():void
            {
                addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
            }
            
            private function onMouseWheelHandler(e:MouseEvent):void 
            {
                maskY -= (e.delta * 4.0);
                dispatchEvent(new Event("scroll"));
            }
            
            private function createBK():void
            {
                graphics.beginFill(0, 0.3);
                graphics.drawRect( 0, 0, _maskWidth + 10, _maskHeight + 14);
                graphics.endFill();
            }
            
            private function createMask():void
            {
                _tfMask = new Sprite();
                _tfMask.graphics.beginFill(0x000000);
                _tfMask.graphics.drawRect(0, 0, _maskWidth, _maskHeight);
                _tfMask.graphics.endFill();
                addChild(_tfMask);
            }
            
            private function createTF():void
            {
                _textFormat = new TextFormat;
                _textFormat.color=_textColor;
                _textFormat.size = 12;
                _textFormat.letterSpacing = 0.75;
                _textFormat.leading = _leading;
                
                _tf = new TextField();
                _tf.textColor = 0xffffff;
                _tf.width = _maskWidth;
                _tf.defaultTextFormat = _textFormat;
    //            _tf.selectable = false;
                _tf.multiline = true;
                _tf.wordWrap = true;
                _tf.autoSize = "left";
                _tf.type = _type;
                _tf.filters = [new GlowFilter(0x000000, 0.95, 2, 2, 10)];
                _tf.mouseWheelEnabled = false;
                addChild(_tf);
                _tf.mask = _tfMask;
            }
            
            private function createFaceContainer():void
            {
                _faceContainer = new Sprite();
                _faceContainer.scrollRect = new Rectangle(0, 0, _maskWidth, _maskHeight);
                addChild(_faceContainer);
            }
            
            private function clearFaceContain():void
            {
                while (_faceContainer.numChildren > 0)
                {
                    _faceContainer.removeChildAt(0);
                }
            }
            
            /**
             * 聊天显示框
             * @param    str 必须为htmlText格式
             */
            public function setText(str:String):void
            {
                _tf.text = "";
                _tf.defaultTextFormat = _textFormat;
                var faceArr:Array = [];
                clearFaceContain();
                
                //保存表情符的编号并替换为空格,此处可以根据你的表情数量来修改正则表达式
                //表情素材的导出类名规则为——face01-face05
                var face:Array = str.match(/\/(0[1-7])/g);
                if (face != null)
                {
                    faceArr = faceArr.concat(face);
                }
                //注意这里是将表情编号替换为全角的空格,所以记住你的输入框要禁止玩家输入全角空格
                //需要替换的内容是:*01 - *09
                str = str.replace(/\/(0[1-7])/g, "<font size='24'> </font>");
                _tf.htmlText = str;
                _tf.height;
                
                //记录空格的索引号
                var text:String = _tf.text;
                var indexArr:Array = [];
                for (var index:int = 0; index < text.length; index++)
                {
                    if (text.charAt(index) == " ")
                    {
                        indexArr.push(index);
                    }
                }
                _tf.height;
                for (var j:uint = 0; j < indexArr.length; j++)
                {
                    var tempPos:Rectangle = _tf.getCharBoundaries(indexArr[j]);
                    var linkClass:Class = _appDomain.getDefinition("face" + faceArr[j].substr(1, 2)) as Class;
                    if (linkClass != null&&tempPos!=null)
                    {
                        var mc:MovieClip = new linkClass as MovieClip;
                        _faceContainer.addChild(mc);
                        mc.x = tempPos.x;
                        mc.y = tempPos.y+3;
                    }
                }
                dispatchEvent(new Event(Event.CHANGE));
            }
            
            /**
             * 设置文本
             * @param    arr 频道数组
             */
            public function setMultiText(arr:Array):void
            {
                if (arr == null) return;
                _tf.text = "";
                _tf.defaultTextFormat = _textFormat;
                var faceArr:Array = [];
                clearFaceContain();
                
                var allStr:String=""
                for (var i:uint = 0; i < arr.length; i++)
                {
                    var str:String = arr[i];
                    var face:Array = str.match(/\/(0[1-7])/g);
                    if (face != null)
                    {
                        faceArr = faceArr.concat(face);
                    }
                    str = str.replace(/\/(0[1-7])/g, "<font size='24'> </font>");
                    allStr += str;
                }
                _tf.htmlText = allStr;
                _tf.height;
                
                //记录空格的索引号
                var text:String = _tf.text;
                var indexArr:Array = [];
                for (var index:int = 0; index < text.length; index++)
                {
                    if (text.charAt(index) == " ")
                    {
                        indexArr.push(index);
                    }
                }
                _tf.height;
                for (var j:uint = 0; j < indexArr.length; j++)
                {
                    var tempPos:Rectangle = _tf.getCharBoundaries(indexArr[j]);
                    var linkClass:Class = _appDomain.getDefinition("face" + faceArr[j].substr(1, 2)) as Class;
                    if (linkClass != null&&tempPos!=null)
                    {
                        var mc:MovieClip = new linkClass as MovieClip;
                        _faceContainer.addChild(mc);
                        mc.x = tempPos.x;
                        mc.y = tempPos.y+3;
                    }
                }
                dispatchEvent(new Event(Event.CHANGE));
            }
            
            /* INTERFACE game.ui.list.IScrollElement */
            
            public function get maskX():Number 
            {
                return _faceContainer.scrollRect.x;
            }
            
            public function set maskX(val:Number):void
            {
                var rec:Rectangle = _faceContainer.scrollRect;
                rec.x = val;
                _tf.x = -val;
                _faceContainer.scrollRect = rec;
            }
            
            public function get maskY():Number 
            {
                return _faceContainer.scrollRect.y;
            }
            
            public function set maskY(val:Number):void
            {
                var rec:Rectangle = _faceContainer.scrollRect;
                if (val < 0) val = 0;
                else if (val > maxScroll) val = maxScroll;
                _tf.y = -val;
                rec.y = val;
                _faceContainer.scrollRect = rec;
            }
            
            public function get minScroll():Number 
            {
                return 0;
            }
            
            public function get maxScroll():Number 
            {
                if (_tf.height <= _tfMask.height) return 0;
                else return _tf.height - _tfMask.height;
            }
            
            public function get tf():TextField
            {
                return _tf;
            }
        }
    }
  • 相关阅读:
    算法设计与分析 5.1 合并果子
    算法设计与分析 4.5 洪尼玛与神秘信封
    算法设计与分析 4.4 洪尼玛与魔法卡
    算法设计与分析 4.3 洪尼玛与芒果篮
    算法设计与分析 4.2 洪尼玛与网络攻防战
    算法设计与分析 4.1 洪尼玛与巧克力工厂
    算法设计与分析 3.5 大尾巴狼
    算法设计与分析 3.4 小鲨鱼
    算法设计与分析 3.3 眯眯眼天使
    算法设计与分析 3.2 小绵羊
  • 原文地址:https://www.cnblogs.com/louissong/p/LouisSong.html
Copyright © 2011-2022 走看看