这两天改别人的代码,涉及到游戏中各种系统提示、警告消息的提示。发现旧的那个公告条,一次只能显示一条,还不能显示html标签,而且还是用到绑定类,这都神马年代了。
改成了可以队列显示,即可以前面一条,后面一条,同时显示多条公告。
1 package com.XXXX
2 {
4
5 import flash.display.Sprite;
6 import flash.events.Event;
7 import flash.events.MouseEvent;
8 import flash.filters.GlowFilter;
9 import flash.text.TextField;
10 import flash.text.TextFieldType;
11 import flash.text.TextFormat;
12 import flash.text.TextFormatAlign;
13
14 /**
15 *
16 * @author ding.jia
17 *
18 */
19 public class SystemNoticeBar extends Sprite implements ISystemNoticeBar
20 {
21 //--------------------------------------------------------------------------
22 // Constructor
23 //--------------------------------------------------------------------------
24 public function SystemNoticeBar()
25 {
26 super();
27 init();
28 }
29
30 //--------------------------------------------------------------------------
31 // Variables
32 //--------------------------------------------------------------------------
33
34 //--------------------------------------------------------------------------
35 // Propertise
36 //--------------------------------------------------------------------------
37 private const GAP:int = 40; //两条公告之间间隔
38 private const MASK_X:int = 72; //文本容器遮罩x
39 private const MASK_WIDTH:int = 609; //文本容器遮罩宽度
40
41 private var noticeMessageQueue:Array;//公告信息队列,一旦在舞台播放就把其从队列里移除,其视图txt还存在noticeViewList于正在播放
42 private var speed:Number;
43
44 //view
45 private var asset:SystemNoticeAsset;
46 private var bg:Sprite;
47 private var maskSprite:Sprite;
48 private var container:Sprite;
49 private var currentLastestTxt:TextField//当前显示的最新的一条公告txt
50 private var noticeViewList:Array;//公告txt先进先出,出去后从队列移除,整体索引自动往前移一位
51 //--------------------------------------------------------------------------
52 // Methods
53 //--------------------------------------------------------------------------
54 public function receiveNotice(message:String):void
55 {
56 //来了一条新信息,如果之前没有正在显示的公告,那么这条就是第一条,直接显示
57 //如果前面有,判断这时是否可以显示新信息还是要等待前一条走到一定距离再显示
58 noticeMessageQueue.push(message);
59 if(checkCanPlayNextNotice())
60 {
61 if(!hasEventListener(Event.ENTER_FRAME))
62 {
63 addEventListener(Event.ENTER_FRAME,enterFrameHandler);
64 }
65 playNewNotice();
66 }
67
68 if(!visible)
69 {
70 visible = true;
71 }
72 }
73 //--------------------------------------------------------------------------
74 // Event Handler
75 //--------------------------------------------------------------------------
76 private function enterFrameHandler(event:Event):void
77 {
78 trace("sytemNoticebat efhander");
79 moveTxts();
80 checkFirstTxtPlayOver();
81 if(checkCanPlayNextNotice())
82 {
83 playNewNotice();
84 }
85 }
86
87 private function containerRollOverHandler(event:MouseEvent):void
88 {
89 speed = 0;
90 }
91
92 private function containerRollOutHandler(event:MouseEvent):void
93 {
94 recoverSpeed();
95 }
96 //--------------------------------------------------------------------------
97 // Private
98 //--------------------------------------------------------------------------
99 private function recoverSpeed():void
100 {
101 speed = 1.5;
102 }
103
104 private function init():void
105 {
106 this.visible = false;
107
108 noticeMessageQueue = [];
109 noticeViewList = [];
110 recoverSpeed();
111 asset = new SystemNoticeAsset();
112 addChild(asset);
113 bg = Sprite(asset.bg_mc);
114 bg.mouseEnabled = false;
115 createTxtsContainer();
116 createContainerMask();
117 }
118
119 private function moveTxts():void
120 {
121 for each(var txt:TextField in noticeViewList)
122 {
123 txt.x -= speed;
124 }
125 }
126
127 private function checkFirstTxtPlayOver():void
128 {
129 var firstTxt:TextField = TextField(noticeViewList[0]);
130 if(!firstTxt)
131 {
132 return;
133 }
134
135 if(firstTxt.x < 0)
136 {
137 var tempNum:int = - firstTxt.x;
138 if(tempNum >= firstTxt.width)
139 {
140 //view过界,可以删除
141 deleteFirstTxt();
142 }
143 }
144 }
145
146 private function deleteFirstTxt():void
147 {
148 var firstTxt:TextField = TextField(noticeViewList[0]);
149 if(firstTxt && container.contains(firstTxt))
150 {
151 container.removeChild(firstTxt);
152 }
153 noticeViewList.shift();
154 checkTotalPlayOver();
155 }
156
157 //检查看是否全部播放结束
158 private function checkTotalPlayOver():void
159 {
160 if(noticeViewList.length == 0)
161 {
162 removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
163 this.visible = false;
164 }
165
166 }
167
168 private function createTxtsContainer():void
169 {
170 container = new Sprite();
171 container.graphics.beginFill(0xff0000,0);
172 container.graphics.drawRect(0,0,bg.width,bg.height);
173 addChild(container);
174 container.addEventListener(MouseEvent.ROLL_OVER,containerRollOverHandler);
175 container.addEventListener(MouseEvent.ROLL_OUT,containerRollOutHandler);
176 }
177
178 private function createContainerMask():void
179 {
180 maskSprite = new Sprite();
181 maskSprite.graphics.beginFill(0xFF00FF,1);
182 maskSprite.graphics.drawRect(MASK_X,0,MASK_WIDTH,bg.height);
183 addChild(maskSprite);
184 container.mask = maskSprite;
185 }
186
187 //播放下一条公告
188 //注意两点
189 //1,这时可能前面还有旧的公告在播
190 //2,新公告的message这时就要从队列里移除,让下一条信息排在队列第一位
191 private function playNewNotice():void
192 {
193 if(noticeMessageQueue.length > 0)
194 {
195 var lastestMessage:String = String(noticeMessageQueue[0]);
196 currentLastestTxt = createNewTxt(lastestMessage);
197 container.addChild(currentLastestTxt);
198 noticeViewList.push(currentLastestTxt);
199 noticeMessageQueue.shift();
200 }
201 }
202
203 //检测等待队列是否为空
204 private function checkQueueEmpty():Boolean
205 {
206 if(noticeMessageQueue.length == 0)
207 {
208 return true;
209 }
210 return false;
211 }
212
213 //检测是否可以显示下一条公告,根据当前最新的公告txt的右端点离舞台右边框的距离值与两条公告 txt间隔比较
214 //当前公告走完会触发,新来一条公告会触发
215 private function checkCanPlayNextNotice():Boolean
216 {
217 if(currentLastestTxt == null)
218 {
219 return true;
220 }
221
222 var tempNum1:int;
223 var tempNum2:int;
224 var tempNum3:int;
225 if(currentLastestTxt.x < 0)
226 {
227 tempNum1 = - currentLastestTxt.x;
228 tempNum2 = Math.abs(currentLastestTxt.width - tempNum1);
229 tempNum3 = bg.width - tempNum2;
230 if(tempNum3 >= GAP)
231 {
232 return true;
233 }
234 else
235 {
236 return false;
237 }
238 }
239 else
240 {
241 tempNum1 = currentLastestTxt.x;
242 tempNum2 = currentLastestTxt.width + tempNum1;
243 tempNum3 = bg.width - tempNum2;
244 if(tempNum3 >= GAP)
245 {
246 return true;
247 }
248 else
249 {
250 return false;
251 }
252 }
253 }
254
255 //创建一条新公告的文本
256 private function createNewTxt(message:String):TextField
257 {
258 var foramt:TextFormat = new TextFormat();
259 foramt.color = 0x00FF00;
260 foramt.size = 15;
261 foramt.font = "宋体";
262 foramt.align = TextFormatAlign.LEFT;
263
264 var txt:TextField = new TextField();
265 txt.defaultTextFormat = foramt;
266 txt.type = TextFieldType.DYNAMIC;
267 txt.x = bg.width;
268 txt.cacheAsBitmap = true;
269 txt.filters = [new GlowFilter(0x000000,0.95,2,2,10)];
270 txt.htmlText = message;
271 txt.width = txt.textWidth + 5;
272 txt.height = txt.textHeight + 5;
273
274 return txt;
275 }
276
277 //--------------------------------------------------------------------------
278 // Dispose
279 //--------------------------------------------------------------------------
280 public function dispose():void
281 {
282 super.dispose();
283 removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
284
285 if(container)
286 {
287 container.removeEventListener(MouseEvent.ROLL_OVER,containerRollOverHandler);
288 container.removeEventListener(MouseEvent.ROLL_OUT,containerRollOutHandler);
289 }
290 }
291 }
292 }