直接上源码,不多说了:
只要有下面这边个类,复制到项目中;运行:TestDialogueUtil.as即可;
package
{
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.Timer;
import flash.utils.getTimer;
/**
* 游戏(剧情)对白(动画)工具
* @author jave.lin
* @date 2013-7-24
*/
public class DialogueUtil{
private static var timer:Timer;
// private static const tfPool:Vector.
= new Vector.
();
//
// private static const dataPool:Vector.
= new Vector.
();
//
// private static const dataArr:Vector.
= new Vector.
(); private static const tfPool:Array = []; private static const dataPool:Array = []; private static const dataArr:Array = []; private static const delay:Number = 60 / 1000; private static const minDelay:Number = 16.6; private static function getData():PopData{ return dataPool.length > 0 ? dataPool.shift() : new PopData(); } private static function pushData(data:PopData):void{ data.tf = null; data.htmlTxt = null; data.duration = NaN; data.complete = null; pushTf(data.helperTf); data.helperTf = null; data.curIdx = NaN; data.update = NaN; data.interval = NaN; data.increaseNum = NaN; data.lastTime = -1; dataPool.push(data); } private static function getTf():TextField{ return tfPool.length > 0 ? tfPool.shift() : new TextField(); } private static function pushTf(tf:TextField):void{ if(!tf) return; tfPool.push(tf); } private static function getDataByTf(tf:TextField):PopData{ if(!tf) return null; for each (var data:PopData in dataArr){ if(data.tf == tf) return data; } return null; } public static function show(htmlTxt:String, tf:TextField, duration:Number, complete:Function = null):void{ //先endShow endShow(tf); //再执行 tf.text = ""; var data:PopData = getData(); data.htmlTxt = htmlTxt; data.tf = tf; data.duration = duration; data.complete = complete; data.helperTf = getTf(); data.helperTf.defaultTextFormat = data.tf.defaultTextFormat; data.helperTf.setTextFormat(data.tf.defaultTextFormat); data.helperTf.multiline = data.tf.multiline; data.helperTf.wordWrap = data.tf.wordWrap; data.helperTf.htmlText = htmlTxt; data.curIdx = 0; data.update = 0; data.interval = duration / data.helperTf.text.length; if(minDelay > data.interval){ data.increaseNum = minDelay / data.interval + (minDelay % data.interval != 0 ? 1 : 0); }else{ data.increaseNum = 0; } dataArr.push(data); start(); } public static function endShow(tf:TextField):void{ var data:PopData = getDataByTf(tf); if(!data) return; data.tf.htmlText = data.htmlTxt; if(data.complete != null) data.complete(); removeData(data); } private static function removeData(data:PopData):void{ var idx:int = dataArr.indexOf(data); if(idx != -1){ dataArr.splice(idx, 1); } pushData(data); } private static function start():void{ if(dataArr.length == 0) return; if(!timer){ timer = new Timer(delay); timer.addEventListener(TimerEvent.TIMER, onTimer); } timer.start(); } private static function onTimer(e:TimerEvent):void{ for each (var data:PopData in dataArr){ popTxt(data); } } private static function popTxt(data:PopData):void{ if(data.lastTime == -1){ data.lastTime = getTimer(); } if(data.curIdx != 0){ var time:int = getTimer(); data.update += time - data.lastTime; if(data.update >= data.interval){ data.update -= data.interval; data.lastTime = time; }else{ return; } } var i:int = 0; if(data.increaseNum != 0){ while(i++ < data.increaseNum && data.curIdx < data.helperTf.length){ pop(data); } }else{ pop(data); } if(data.curIdx >= data.helperTf.text.length){ endShow(data.tf); if(dataArr.length == 0){ timer.stop(); } } } private static function pop(data:PopData):void{ var endIdx:int = Math.min(data.curIdx + 1, data.helperTf.length); var format:TextFormat = data.helperTf.getTextFormat(data.curIdx,endIdx); var newChar:String = data.helperTf.text.charAt(data.curIdx); if(newChar == '\r'){ newChar = '\n'; } data.tf.appendText(newChar); data.tf.setTextFormat(format,data.curIdx, endIdx); data.curIdx++; } } } import flash.text.TextField; class PopData{ public var tf:TextField; public var htmlTxt:String; public var duration:Number; public var complete:Function; public var helperTf:TextField; public var curIdx:int; public var update:Number; public var interval:Number; public var increaseNum:int; public var lastTime:int = -1; }
调整部份:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* description
* @author jave.lin
* @date 2013-7-24
*/
[SWF(width="1000",height="600")]
public class TestDialogueUtil extends Sprite{
private var tf:TextField;
private var tf1:TextField;
private var tf2:TextField;
public function TestDialogueUtil(){
super();
stage.frameRate = 60;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.color = 0x888888;
tf = getTf();
tf.x = 100;
tf.y = 100;
addChild(tf);
tf1 = getTf();
tf1.x = 250;
tf1.y = 100;
addChild(tf1);
tf2 = getTf();
tf2.x = 400;
tf2.y = 100;
addChild(tf2);
var msg:String = "你好lsdjfalkdfjafdasdfafafdadfadfadfadfafaladjflakdjflasdjflakjdflaksjdflaskdjflaskdjflakdsjflaskdjf";
DialogueUtil.show(msg, tf, 10000, complete);
tf1.htmlText = msg;
DialogueUtil.show(msg, tf2, 5000, complete);
function complete():void{
trace("complete");
}
function getTf():TextField{
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
var format:TextFormat = tf.defaultTextFormat;
format.size = 12;
format.color = 0xffffff;
format.font = "Simsun";
tf.defaultTextFormat = format;
tf.setTextFormat(format);
// tf.width = 100;
// tf.height = 500;
tf.multiline = true;
tf.wordWrap = true;
tf.border = true;
tf.borderColor = 0;
tf.background = true;
tf.backgroundColor = 0x888888;
return tf;
}
stage.addEventListener(MouseEvent.CLICK, onClick);
tf.addEventListener(TextEvent.LINK, onLink);
tf1.addEventListener(TextEvent.LINK, onLink);
}
private function onLink(e:TextEvent):void{
trace(e.text);
}
private function onClick(e:MouseEvent):void{
DialogueUtil.endShow(tf);
}
}
}
效果图: