Director中事件发生的顺序及其意义
我开始学习lingo的时候,在几个困扰我的几个严重问题中,事件的执行顺序就是其中之一,所以我现在把它们的整理出来,希望对还被这个问题骚扰的同志们有所帮助(部分资料来自aougu的lingo词典)。如果那位有补充,欢迎跟帖。
基于方便起见,假设一个电影中只有一个精灵而且只有第一帧,那么事件的执行顺序是这样的:
-- "preparemovie"
-- "beginSprite"
-- "prepareframe"
-- "startmovie"
-- "enterFrame"
-- "exitFrame"
-- "stopMovie"
-- "endSprite"
下面分别说明:
-- "preparemovie" :
系统消息和事件处理程序;所包含的语句在电影调入演员后、做下列事情前执行:
建立所播放的第一帧中sprite所属行为的实例。
预备播放第一帧,包括画出此帧,播放任何声音、以及执行过渡和调色板效果。
用于第一帧sprite行为的新全局变量应在处理程序on prepareMovie中初始化
。在以前的电影已经设定的全局变量无需复位。 处理程序on prepareMovie是一个放置lingo的好地方,以建立全局变量、初始化变量、在电影其余部分调入内存的同时播放声音、或检查与调整计算机状态(如色深)的好地方。
*此时,电影中的第一帧的演员已经载入,但是还没有进行初始化,因此这里可以对电影进行初始化,但是可能很多针对精灵,演员等具体内容的命令不能正确执行。
-- "beginSprite":
系统消息和事件处理程序,当播放头进入一帧,这一帧里首次出现了某个sprite时运行包含的语句。象endsprite,即使播放头在这一帧上循环,这个事件也将只发生一次。这是因为触发事件的sprite不是首次出现。这个事件在prepareframe前发生。当beginsprite的消息被发送的时候, Director会给任一附在这个sprite上的事件脚本建立一个实例。如果被使用在行为上,对象参数me会忽略这个事件。这条消息将被发送到行为和帧脚本。如果一个sprite在电影的第一帧出现,那么beginsprite的消息将会在prepareMovie后但在prepareframe和startmovie事件前发送。
注意:
需要注意某些sprite属性,如rect属性可能就不能受begainsprite处理程序的
控制。因为这个属性需要计算,并且在舞台更新以前不能完成。
*由于这个事件之出现一次,所以这是个把对精灵脚本甚至帧脚本初始化的好地方,如设定属性变量的初始值等。
-- "prepareframe":
系统消息和事件处理程序;包含的语句在画当前帧以前立即执行。 与
beginSprite和endSprite事件不同,每次播放头进入帧时都产生prepareFrame
事件。 处理程序on prepareFrame是一个在sprite画出前改变sprite属性的有
用的地方。
如果用于行为,处理程序on prepareFrame接收me引用。
*此时,第一帧已经准备完毕,所以完全可以对精灵,演员的属性等进行控制,这里是一个更改属性的好地方。
…注意…由于以上三个事件发生的时候,精灵还没有画出,所以命令go,
play和updateStage在处理程序内无效。
-- "startmovie":
影片事件处理程序,当影片的第一帧刚刚显示完毕时,该处理程序被调用。
*好像不多用,当然,有些命令可能需要放在这里,如go,play等。
-- "enterFrame":
系统消息和事件处理程序;每次播放头进入该帧的时候就执行包含在里面的语句. on enterFrame事件处理程序放在行为,帧或者电影脚本中.像下面这样:
要分配一个处理程序给独立的sprite, 把处理程序写进一个附在sprite上的行为中.
要分配一个处理程序给独立的帧, 把处理程序写进帧脚本.
分配处理程序到每一个帧中, 把 on enterFrame 处理程序写入电影脚本中.
处理程序每次会在播放头进入一帧的时候执行除非帧脚本由自己的处理程序. 如果帧脚本由自己的处理程序, 帧脚本中的on enterFrame
会忽略电影脚本中的on enterFrame处理程序.
*此时,当前帧已经画出,所以这时候改变精灵的属性并不是令人称道的事情,因为很可能会导致画面的闪动。当然,还是有些脚本可以在有预谋在这里使用。
-- "exitFrame":
系统消息和事件处理程序;exitFrame包含的语句将在每次播放头退出该帧的时候执行. onexitFrame 处理程序是一个比较有用的地方来使得lingo重新设置离开帧之后的环境。on exitFrame事件处理程序放在行为, 帧或者电影脚本中,就像下面这样:
分配处理程序给独立的sprite, 把处理程序写在依附在sprite上的行为中. 分配处理程序给独立的帧, 把处理程序写在帧脚本中. 分配处理程序到每个帧除非有其他额外的条件,否则就把处理程序放在电影脚本中. on exitFrame处理程序就在每次播放头退出一个帧的时候生效,除非这个帧有自己的on exitFrame处理程序. 当该帧脚本有自己on exitFrame处理程序的时候, 该帧on exitFrame 处理程序取代电影脚本中的那个处理程序.
*众所周知,这是我们使用最频繁的事件,很多脚本都推荐在这里使用。我的原则是:如果能在这里使用,那么我不会放到别的什么地方去。
-- "stopMovie":
系统消息,影片事件处理程序。当影片停止或结束时,该处理程序运行。
*此时,已经运行结束,如果你在电影运行的时候曾使用程序更改过某些东西的话,也许你应该在这里把它恢复过来。
-- "endSprite":
系统消息和事件处理程序;在播放头离开一个sprite并且进入了一个不存在该sprite 的帧中的时候,执行其中包含的Lingo语言. 他在exitFrame以后发生.endSprite事件处理程序放在行为脚本中.一旦endSprite事件发生,Director就破坏附在Sprite上的任何行为脚本的例程.如果这个事件在一个行为中被使用,他将被传递到行为或者帧脚本所引用的me对象去.如果播放头播放到了一帧的结束endSprite消息将在exitFrame消息之后发送. go , play , 和updateStage命令在on endSprite处理程序中无效.
*老实说,我绝少用到这个事件,因为我感觉在这里我几乎做不来什么,也许能消除些什么?
以上内容简单来说就是这样的:
-- 电影调入演员,电影属性等;
-- "preparemovie"
-- 播放头进入第一帧,实例化脚本;
-- "beginSprite"
-- 当前帧准备完毕;
{
-- "prepareframe"
-- 画当前帧;
-- "startmovie"
-- "enterFrame"
-- 播放头处于当前帧中;
-- "exitFrame"
-- 播放头退出当前帧;
}
{}之间的循环,(可能在某处有beginsprite或endsprite)
-- "stopMovie"
-- 电影停止;
-- "endSprite"
-- 精灵结束。
补充:还有一个事件 --stepFrame, 我不很熟,所以没有写出来,执行顺序是在紧挨prepareFrame之前,希望有那位补充上。
周末抽点时间看了一下书,然后再试了一下,才发现StepFrame的功能其实也很强大,不过我用得不多,把我的想法说出来大家参考一下吧。
-----StepFrame :
oop事件处理程序,任何添加到actorlist里面的剧本对象都在每一帧发送一次该消息。
----actorList :
影片属性;一个有外部子对象存入的列表。每当播放头进入帧时actorList中的对象接受一个stepFrame信息。
向actorList加入一个对象时,使用" add actorList , theObject"。父脚本或ancestor脚本中的对象,在播放头每移到新的一帧时自动被调用。清除actorList中的对象,用" set actorList to [ ]",将它设为空列表。
当actorList在另外的影片中有分枝时,Director不能清除其中的目录,原因是在新影片中有不可预知的行为。预防当前影片中的子对象从一个新影片上移过,在新影片的" on prepareMovie "名柄中插入指令" set the actorList = [ ]"
*举个例子吧,
----moviescript中----
on stepframe
me . loc = point ( random ( 800 ), random ( 600 ))
end
这样如果你在其他语言中向 actorList 加入一个对象X,那么每一次stepframe事件发生的时候,都会对这个对象执行:X. loc = point ( random ( 800 ), random ( 600 )) ,如果actorList中有多个对象,则从前往后一次执行命令。
当然你可以向actorList中添加任何内容,只要与stepframe中的语句不冲突就行了。这样,每次stepframe事件发生的时候,都会向actorList中的所以对象发送一个stepframe中的执行语句。
*作用:可以用来监测电影的运行以及电影中始终需要更新的变量以及其他对象。