又复习Lingo中关于Script的各种概念。
Behavior:"Behavior是一组Handler的集合"。
Handler:"是处理Event的方法/函数"。
Event:"系统或用户定义的特定情况。"嗯,没错,这里的Event确实分为system和user-defined两类。就system而言,又分成两类,一类是会自动发生的,一类是需要人为触发的(mouseUp..)。这个区分没多大意思,这么分只是为了下面的"自动发生的system Event的执行顺序"。
自动发生的System Event的顺序
movie开始帧:prepareMovie à beginSprite(开始帧的) à prepareFrame à startMovie
注:director11.5 的script dictionary文档中,这里beginSprite和prepareFrame的顺序弄反了。
中间帧内:beginSprite(本帧) à stepFrame àprepareFrame à enterFrame à exitFrame à endSprite(本帧)
注:stepFrame是parent script的system event。写在frame behavior中的on stepFrame是没有用的。
movie结束帧:endSprite(结束帧的) à stopMovie
而下图也是一个错误(或过时)的图示。帧内的事件,xxxFrame这样的都是位于beginSprite和endSprite之间。
Handler如何能得知Event
如果Handler有手机那Director可以在Event发生是打电话给它。但它没有,所以Director就发Message给Handler。
Message:Event发生时Director通知Handler的通信方式。
问题来了,如果Handler很多呢?譬如,一个按钮,它的cast script有翻转效果,mouseUp背影色会变;它的sprite的鼠标单击会停止播放;同时该帧上单击事件发生时会刷新屏幕某个位置的一个显示帧数的数字;再同时整个movie会记录整部影片中鼠标单击了多少次。以上四个功能分别对应的脚本是:
cast member script: 按钮翻转效果
sprite behavior: stop功能
frame behavior: 返回 frameNum
movie script: 刷新clickNum
(为了把四种脚本弄出来,这个例子必须别扭。)
当这个按钮被单击时,以上四种脚本中的mouseUp Event的Handler接收到mouseUp Message的顺序是:(广告后马上回来..)
Director向不同脚本中的Handler发Message的顺序
sprite behavior à cast member script à frame behavior à movie script
嗯,想必马上就注意到了,像sprite behavior这样的,一个sprite会有很多behavior,对它们的顺序又是怎样的?
答案很有逻辑,就是按照添加的顺序。也就是behavior在sprite(num).scriptInstanceList中的顺序。
为啥movie script的mouseUp就是不响应?
在前述4类Handler之前还有一个类似默认Handler的东东,形如on mouseUpScript,它和上边四类的Handler的有点不一样,它在执行完自己之后,会继续依次向后转发消息,当然也可以关闭,dontPassEvent。而上述4类的Event Handler,必须手动在最末添加pass()。譬如sprite 的on mouseUP最后如果不写上pass()语句,那么在处理结束之后,这个Event就算到底为止了。
因此,在各层级的Handler尤其是system event handler,尤其要确认到底要不要pass()。
回头再看Handler
Handler是响应Event的代码,事件处理器 Event Handler,就是个函数。
这个函数当然是写在一个script中,但这个script的类型和_________就有点意思了。
空白处一会儿再来补充。(script附着的对象)
再复习script的类型
director中script有两种,lingo和javascript。——不是这个意思!
director中script有三种:behavior,movie和parent。——对了,就是这个意思。
这三种也就是新建一个script时,在它的property Inspector窗口中看到的3个可选Type。
(友情放送快捷方式:script window Ctrl+0零,property Inspector Ctrl+Alt+S;)
(再友情放送当前movie属性的快捷方式Ctrl+Shift+D,这个快捷方式其实也是打开property Inspector,只是马上定位到movie标签。)
这三种类型比较明显的区别就是,behavior可以附着(拖到score中)在Frame/Sprite上,而movie和parent不能。
另外behavior和parent有me的概念,即是说他们的存在方式就是1.behavior的附着;2.parent的child化。
movie这类script就相当于当前项目中全局可以访问的区域,除了全局的System Event Handler写在这里,也可以写一些全局访问的函数在此。它虽然也是一个单独的script member的形式,但它的存在更像c++中的只有static方法的abstract,没有me一说。
接着Handler,根据需要把函数放在不同类型和附着于不同位置的script中。
关于如何创建和使用某类型的script,俺还是想把你和N天后的俺都当成纯智障来解释一下。它是这样的(广告后马上回来…)
如何创建script
创建script的方式很多,你可以:
sprite右键选择script
这时script window会topset并且自动创建一个已经attach到sprite的behavior。
单击发生的事情包括:1创建了一个script member,类型是behavior;2这个behavior已经attach到sprite,也就是在sprite的scriptInstanceList中你能找到了。
双击script channel的某一帧
这是在script window中自动创建的仍然是一个behavior,但它attach到的是Frame,是一个frame behavior。
在behavior script中,都有me。这个必须有。
在script window中点+
此时新建script的Type貌似是用上一次的script的Type。
如果想创建的是一个movie,那么property window中保证Type对了以后就可以直接type script。
如果想创建的是behavior,那除了以上操作,在敲完键盘以后,你还得让它attach到frame或prite上。attach的方式也有很多,GUI的方式就有:1,拖动script member到score;2,拖动script member 到stage;3,选中sprite或frame在behavior inspector中点+添加。(behavior inspector 快捷键Ctrl+Alt+;)
如果想创建的parent,跟movie一样。只是使用时,必须要new出一个child才行。
cast member右键选择 cast member script
这种比较奇怪,你甚至在property inspector中看不到它到底是什么Type。同时也只有这种script,它不会在cast中添加一个新的script member。
这两点逻辑上很一致,但总让然感觉不和谐的地方是,cast member script明明是script,却没有被纳入script member麾下。
其他方面,比如它内部的handler如何处理Event,前面已经提过,Director还是拿它和其他的script一起系统管理的。
还有一点要注意,一个cast member有script,并不代表师从它的sprite一定会执行。需要在behavior inspector中手动添加,仍然是按那个+。(behavior inspector 快捷键Ctrl+Alt+;)
另外,别忘记向后转发Event Message的命令pass()。