浅谈怎样在Director中建立更敏捷的系统

      多媒体世界 2006-6-16 17:10
浅谈怎样在Director中建立更敏捷的系统
怎么在director中建立易阅读,且易扩展的系统一直是Director程序员们努力追求的目标之一。但Director只是一门脚本语言,对面向对象技术支持并不不是很完善,所以很多在C++,java中可以运用的方法,及程序设计思想,在director中是无法直接运用的,在这一点上flash做的比director好。
但是这并不意味着director完全不能借鉴他们的的程序设计思路,在设计模式中最常用的观察者模式和委托事件模式我们就可以很好的借用到director中来。
我改写了director mx2004目录下的一个学习的例子C:\Program Files\Macromedia\Director MX 2004\Learning\Lingo\lingo QT and Flash.dir。对比我上传的例子,你应该会有一个比较清晰的理解。
在我的例子中,关键是EventObj对象。其具体程序如下:
----------------------------------------------------------------------------------
property ObjserverList --观察者模式列表
on new me
ObjserverList=[]
return me
end

on addListenerObj me,EventName,RegSpr --注册的精灵和其注册的事件
tchange=0
listLength=objServerList.count
repeat with i=1 to listLength
if ObjServerList[i].getPropat(1)=symbol(EventName) then --事件列表中有这个精灵
if objServerList[i][symbol(EventName)].getOne(regSpr)=0 then
objServerList[i][symbol(EventName)].append(regSpr)
end if
tchange=1
end if
end repeat
if tchange=0 then
tlist=[:]
tlist.setaprop(symbol(EventName),[])
objServerList.append(tlist)
objServerList[listLength+1][symbol(EventName)].append(regSpr)
end if

end
on removeListenerObj me,EventName,RegSpr --撤销精灵的注册事件
tchange=0
repeat with i=1 to objServerList.count
if ObjServerList[i].getPropat(1)=symbol(EventName) then --事件列表中有这个精灵
objServerList[i][symbol(EventName)].deleteOne(regSpr)
if objServerList[i][symbol(EventName)].count=0 then
objServerList.deleteAt(i)
end if
tchange=1
end if

end repeat
if tchange=0 then
put "The Event isn't exist!"
end if

end
on BroadMsg me,EventName,EventSource --主题发出广播
repeat with i=1 to objServerList.count
if ObjServerList[i].getPropat(1)=symbol(EventName) then
repeat with j=1 to objServerList[i][symbol(EventName)].count
call (symbol(EventName),objServerList[i][symbol(EventName)][j],EventName,EventSource)
end repeat
put "send Msg success!"
return
end if
end repeat
put "No Event"
end
--------------------------------------------------------------------------------------------------------
在影片开始处添加以下程序初始化EventObj对象
-----------------------------------------------------------------------------------------------------------
global geventObj
on preparemovie --生成一个事件控制对象
gEventObj=script("eventObj").new()
end
--------------------------------------------------------------------------------------------------------------
在电影的附加以下行为,主要是注册接受五个事件和发出一个事件及定义事件处理程序
--------------------------------------------------------------------------------------------------------
global gEventObj
property pDuration,vvalue
on beginsprite me
pDuration=sprite(me.spritenum).duration
--侦听以下的事件
gEventObj.addListenerObj("play",me)
gEventObj.addListenerObj("stop",me)
gEventObj.addListenerObj("backward",me)
gEventObj.addListenerObj("forward",me)
gEventObj.addListenerObj("rewind",me)
gEventObj.AddListenerObj("dragbar",me)
end
on prepareFrame me
vvalue = float (sprite(me.spritenum).movietime) / pDuration
gEventObj.broadMsg("NowMovieTime",me) --广播事件
end
--侦听到的事件由下面函数处理
on dragbar me,EventName,Eventsource
-- pSpriteNum, pPosition
sprite(me.spritenum).movieTime = integer (pDuration * Eventsource.pPosition)
end

on play me
put "play"
sprite (me.spritenum).movieRate = 1
end

on stop me
put "stop"
sprite (me.spritenum).movieRate = 0
end

on backward me,EventName,Eventsource
put "backward"
if the mouseDown and rollover (Eventsource.spriteNum) then

sprite (me.spritenum).movieRate = -2
else
sprite (me.spritenum).movieRate = 0

end if
end


on forward me,EventName,Eventsource
put "forward"
if the mouseDown and rollover (Eventsource.spriteNum) then
put "MovieRage=2"
sprite (me.spritenum).movieRate = 2
else
sprite (me.spritenum).movieRate = 0
put "MovieRage=0"
end if
end
on rewind me
put "rewind"
sprite (me.spritenum).movieRate = 0
sprite (me.spritenum).movieTime = 0

end
--------------------------------------------------------------------------------------
在各个按钮上面则附加下面的行为:
--------------------------------------------------------
global gEventObj
property EventName

on mousedown me
gEventObj.BroadMsg(EventName,me) --广播事件
end
on mouseup me
if EventName="backward" or EventName="forward" then
gEventObj.BroadMsg(EventName,me) --广播事件
end if
end

on getpropertydescriptionlist me
plist=[:]
setaprop plist,#EventName,[#comment:"请输入事情名",#format:#string,#range:["play","stop","backward","forward","rewind"],default:"play"]
return plist
end
---------------------------------------------------------------
这样一个基本的电影控制就完成了。

如果用户需求改变需要用一个文本演员显示电影播放的进度,则只需要建立一个文本演员,然后侦听相应的事件即可,行为如下:
----------------------------------------------------------
global gEventObj
on beginsprite me
gEventObj.addlistenerObj("NowMovieTime",me) --侦听nowMovieTime事件
end
on NowMovieTime me,EventName,EventSource
sprite(me.spritenum).member.text=string(EventSource.vvalue)
end
------------------------------------------------------------------

关于播放条,我修改了部分程序,既增加了三个地方:
在beginsprite的时候
gEventObj.addlistenerObj("NowMovieTime",me)
然后定义了一个nowMOvieTime的函数用来处理相应的事件。


这只是一个最基本的例子,在实践中,我们往往需要扩展这个程序。希望本文可以给广大Director爱好者一些启迪。
最后感谢我在高山的大哥老张,和他的探讨给了我很多的思路。
相关请看:
www.aougu.net/bbs/index.php?prog=topic::flat&tid=36594&page=end
标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commenttime}{commentauthor}

{CommentUrl}
{commentcontent}