#52002/11/29 0:32:00
以前写的一篇文章,你看看,也许对你有用。
在用Director开发多媒体软件时使用声音是件很平常和容易的事。这都得益于director中众多的声音通道(有8个之多)。在 score 中有两个通道是专门用于播放声音的(如图),也是最常用到的,只要把声音演员拖放到上面,再调整一下它的长短和位置就行了,但是这种方法缺乏灵活性。解决的方法就是用lingo,lingo播放声音的命令有:
puppetSound whichChannel, whichCastMember;
sound playFile whichChannel, whichFile;
sound(channelNum).play([#member: member(whichmember), {#startTime: milliseconds, #endTime: milliseconds, #loopCount: numberOfLoops, #loopStartTime: milliseconds, #loopEndTime: milliseconds, #preloadTime: milliseconds
}])
是不是有点头昏?^_^ 其中最后一条最少用到也是最有用的一条,也是这篇文章用到的语句,我也将在下面做一些介绍,不过现在就买个关子,:>
上面说了一大堆都是不着题的东西,是不是跑题了?好现在就回到正题来。director中暂停声音可以用sound(channelNum).pause(),重新播放就用sound(channelNum).play()。这可能就有人问了:这么简单?你早写出来不就行了,这么罗嗦!其实不然,以上的两个命令是有局限性的,sound(channelNum).pause()可以暂停任何形式播放的声音(包括score中的两个通道和用lingo语句播放的声音),但是如果你想用sound(channelNum).play()来重新播放被pause的声音,那么你只能把声音放在score中的两个声音通道中。对于用lingo播放的声音只能从头开始播放,不会从暂停处继续播放。怎样解决这个问题呢?如果你仔细读了前面我所列的三个命令中的最后一个,我想你就会有解决方法了。你继续往下读这篇文章吗?
其实解决的方法很简单:暂停时读取声音播放到的时间位置,下次再播放时只要从那个位置开始放就行了。要在Director中实现上面的方法,有两个语句是很关键的,一个是上面说到的sound(ChannelNum).play(...);另一个就是:sound(ChannelNum).currentTime 它返回的是第ChannelNum个声音通道中声音播放到的时间。对于sound(ChannelNum).play(...)的使用方法,我这里只做简单的介绍,具体的用法你可以去读director的帮助。它可以控制声音从任何起点开始播放和结束于哪里和在什么范围内循环多少次,在这篇文章中我们只用到它的两个参数:#member和#startTime。#member:指明要播放哪一个声音演员,#startTime:指明播放的起点,它是一个代表毫秒的整数(1000毫秒=1秒)。
例如:
sound(2).play([#member: member("creditsMusic"), #startTime: 4000])
指从第四秒开始播放声音演员:"creditsMusic"。
要使用sound(ChannelNum).play(…)这个语句,就必需知道要播放哪个声音演员。不过不要紧,我们有 sound(ChannelNum).member 这个语句,它可以返回正在通道里播放的声音演员,这样我们编程时就可以只针对通道而不是声音演员了,程序就有更大的广泛性和适用性。
下面的一段程序就能实现暂停/继续播放声音的功能。全部变量必需声明为 global 或 property 类型,并且要初始myResume=1。因为它们是用来记忆当前单击时声音的各种状态,
myResume=1
on mouseUp me
if myResume and soundBusy(mySoundChannel) then -- 等于 1 时是暂停,等于 0 时是播放
mySoundMember=sound(mySoundChannel).member -- 取得正在播放的声音演员
sound(mySoundChannel).pause() -- 暂停,不能用stop(),因为它会使用播放时间变为0
mySoundTime=sound(mySoundChannel).currentTime -- 读取时间
myResume=0
else
if sound(mySoundChannel).isBusy() then
sound(mySoundChannel).play([#member: mySoundMember,#startTime:mySoundTime])
myResume=1
end if
end if
end mouseUp
为了使我们的程序有更广泛的适用性,我们把它写成一个行为,以下就是这个行为的全部代码,你可以在它的基础上根据需要扩展它,使用的功能更加强大。我就是在它的基础上扩展出几个行为,并做成一个小小的行为库,如果你想要你可以下载回去用,如果你觉得好用可以把它放到Director的libs目录内,这样你就可以像用director的其它的行为一样的方便了。还要说明一下的就是,以上的代码和行为库全部都是在director8内完成的。
property myResume
property mySoundMember
property mySoundTime
property mySoundChannel
on getBehaviorTooltip me
return \
"暂停和重新播放声音"
end getBehaviorTooltip
on getBehaviorDescription me
return "可以暂停某个通道声音的播放,并且可以再次从暂停的位置开始向下播放." & RETURN & \
"本行为由 南山东篱小组 东影默 编写."
end getBehaviorDescription
on beginSprite me
myResume=1
end beginSprite
on mouseUp me
if myResume and soundBusy(mySoundChannel) then
mySoundMember=sound(mySoundChannel).member
sound(mySoundChannel).pause()
mySoundTime=sound(mySoundChannel).currentTime
myResume=0
else
if sound(mySoundChannel).isBusy() then
sound(mySoundChannel).play([#member: mySoundMember,#startTime:mySoundTime])
myResume=1
end if
end if
end mouseUp
on isOKToAttach (me, aSpriteType, aSpriteNum)
case aSpriteType of
#graphic:
return TRUE
#script:
return FALSE
end case
end isOKToAttach
on getPropertyDescriptionList
return [#mySoundChannel : [ \
#comment: "Sound channel:", \
#format: #integer, \
#default: 1, \
#range: [1, 2, 3, 4, 5, 6, 7, 8]]]
end getPropertyDescriptionList