自flash的新版本语言ActionScript3.0发布以来已经过了不少时间,想必大家都已经从当初2.0与3.0的变化中缓了过来,但对新手而言,想要用AS3.0来实现特定功能仍然有一定难度,在这里就简单介绍下我曾经遇到过的问题,对播放控制进度条的制作及其对声音的控制这一块作些简单介绍。为了让和我一样处于起步阶段的同胞少走弯路,高手请自动忽视。
每当看到别人制作出的flash作品时,大家都会发现上面会有个播放控制进度条,可以通过拖动进度条来方便的实现快进快退,从而能够实时的控制自己的观看进度。因此,一个好的flash作品基本都会配备一个进度条,既增强了交互性又能方便观众,何乐而不为呢?
那么我们自己怎么制作进度条呢,可能有不少人在网上疯狂搜索,可是基本上能找到的都是用AS2.0写的,让我们就这样把代码弄到我们的作品中显然是不现实的,因为2.0和3.0的版本变化还是比较大的。因此,我在借鉴了网上相关作品的基础上,对其加以改进整合,制作出了用3.0语言写的播放进度条,使其能够完美实现进度条这个功能,废话不多说了,下面贴代码:
作一个滑块和一个进度条,然后两个组合一下就成了播放控制进度条合的话要改一下数据,这个我代码中会标记在哪改。
下面是代码,写在进度控制这个元件里,三个都用影片剪辑就可以了
如下图:
代码如下:
import flash.events.MouseEvent;
import fl.motion.MotionEvent;
//progressBar是进度条的名称,slider是滑块的名称
//滑块的状态
//动态获取滑块的x坐标
var drag:Boolean= false;
var sliderX:Number;
//滑块的滑动范围,前面两个参数分别是滑块和进度条重合的x和y坐标,开始没对齐的可以用这个改坐标使滑块和进度条对齐
//后面两个参数是横向偏移量和纵向偏移量
var rect:Rectangle = new Rectangle(0, -27.25,progressBar.width, 0);
//ENTER_FRAME事件,即时更新滑块的位置
addEventListener(Event.ENTER_FRAME,EnterFrameHandler);
function EnterFrameHandler(e:Event):void
{
//自然播放的结果
if (drag == false)
{
//获取主场景中的currentFrame和totalFrames,并算出滑块的x坐标
sliderX = root["currentFm"]/(root["totalFm"]/progressBar.width);
slider.x = sliderX;
}
//认为滑块拖动之后的结果
if (drag == true)
{
MovieClip(root).gotoAndStop(Math.floor((Math.abs(slider.x)+1)*(root["totalFm"]/progressBar.width)));
}
if (slider.x<=0 && drag == true)
{
slider.x = 0;
MovieClip(root).gotoAndStop(1);
}
if (slider.x>=progressBar.width)
{
drag = true;
}
//安上进度条后从最后一帧跳到第一帧,这边2280是我的flash最后一帧的前一帧方便侦听,
//需要的自行更改
if(root["currentFm"]==2280)
MovieClip(root).gotoAndPlay(1);
}
//注册事件侦听
//鼠标左键在滑块上按下
//鼠标左键在滑块上抬起
//鼠标左键在进度条上按下
//鼠标左键在进度条上抬起
slider.addEventListener(MouseEvent.MOUSE_DOWN,slider_DOWN);
slider.addEventListener(MouseEvent.MOUSE_UP,slider_UP);
progressBar.addEventListener(MouseEvent.MOUSE_DOWN,progressBar_DOWN);
progressBar.addEventListener(MouseEvent.MOUSE_UP,progressBar_UP);
//事件侦听函数
function slider_DOWN(evt:MouseEvent):void{
evt.target.startDrag(false,rect); //按住滑块,滑块随鼠标拖动
drag=true;
stage.addEventListener(MouseEvent.MOUSE_UP, slider_UP); //在舞台上添加一个监听器
//防止出现在滑块上按下在其他位置抬起的情况
}
function slider_UP(evt:MouseEvent):void{
stage.removeEventListener(MouseEvent.MOUSE_UP, slider_UP); //移除在舞台上抬起左键时的监听器
stopDrag();
drag=false;
MovieClip(root).play(); //鼠标左键抬起后主场景继续播放,需要暂停的写stop()
}
function progressBar_DOWN(evt:MouseEvent):void{
drag=true;
slider.x=mouseX;
}
function progressBar_UP(evt:MouseEvent):void{
drag=false;
MovieClip(root).play();
}
上面的就是进度控制条的代码了,不过大家肯定会发现还有两个东西没定义,没错,就是currentFm和totalFm,不过不用担心,这两个都是主场景的,只需要在主场景的第一帧加上这么一段代码就可以使用了,
var totalFm:Number=totalFrames;
var currentFm:Number;
addEventListener(Event.ENTER_FRAME,reflash);
function reflash(e:Event):void{
currentFm=currentFrame;
}
恩,对于只需要播放进度控制条这一块的朋友,那么看到这里就可以了,上面的代码都是可以直接拿去用的,不过你以为我会这样就结束了?注意看我的标题,没错,是播放控制进度条与控制声音的两种模式,进度条说完还有声音控制这一块呢,那么接下来就进入第二块内容——进度条对声音的控制。
想来不少朋友刚做这一块的时候都要求加入声音吧,那么简单的导入声音什么的我想大家都会了,导入到库或者导入到舞台都可以,想要与动画同步的话设置成数据流格式即可,这边估计没人会有疑问。那么接下来就是让声音与进度条同步的问题了,
对于只有一种声音,直接导入到主时间轴上的并让它随着时间轴的播放而播放的这种情况,我们只需要静观其变,对就是什么都不做,因为我们使用的的是MovieClip(root)来控制主场景随着进度条的移动而移动的,而当一种音乐以数据流格式导入到主时间轴上时,该音频也会和主场景上其他元件一样与进度条进度一致,所以不需要作什么改变。
那么接下来介绍第二种放置音乐的办法,那就是导入到影片剪辑里,相信肯定有不少人卡在这方面上,以致见到影片剪辑元件就是又爱又恨。那么相比直接导入主时间轴上,导入到影片剪辑有什么好处呢?大家都知道影片剪辑就相当于一个小的独立的swf文件,它有自己独立的时间轴,而且能用actionscript3.0语言对它进行控制。不过虽然把声音导入到影片剪辑(以下简称MC)中是很有好处的,但是如何用进度条进行控制就成问题了。以往直接导入声音时,声音随进度控制,让它停就停,让它播就播,像个乖宝宝一样。然而一进入MC中立马开始使坏,不是播了停不下来就是在重复播,到处写满了stop();不是空属性错误就是停不下来,感觉很容易让人找不到头绪。其实我开始也是这样,一行一行的注释,一行一行的写停止,到了测试的时候正常播放或者把进度条往后拖还好,一旦往前拖就会出现从MC开头播放的问题,往前点几次就播放几次,那声音组合起来听起来简直是“天籁之音”,折磨的人发狂。好吧扯远了,接下来就说说怎么解决吧。
解决方法当然是很简单的,因为MC元件中放入声音后,即使有时候你写了停止,但是在停止之前,已经触发了MC的第一帧,然后MC中的声音就开始播放了,这时你要做的就是在第一帧加入空白帧,如果音频前几帧不重要的话也可以拆分音频把第一帧转为空白关键帧,这样通过进度条往前拖拉时就不会出现MC自动播放的问题了。
那么解决完这个,那就是如何控制音频播放进度的问题了,同样的,只要把上面的 MovieClip(root).gotoAndStop(Math.floor((Math.abs(slider.x)+1)*(root["totalFm"]/progressBar.width)));
这句代码复制一下然后稍作修改即可,假设放音频的MC实例名是mc,那么控制mc的代码就是下面这句
root["mc"].gotoAndPlay(Math.floor((Math.abs(huakuai.x)+1)*(root["totalFm"]/bar.width))+X);
此句中的“+X”是可以改变音频提前或延迟播放的帧数,也可以在MC中手动修改,正好合适的就可以删掉“+X”,
这样就实现了用进度条控制MC存放的声音的功能。
另外再说一些功能,如果想要控制播放到指定帧可以用gotoAndPLay(); 或者gotoAndStop();
如果想控制mc在哪些帧不播放只需要在进度控制中加以下代码: if(root["currentFm"]<=25)
root["mc"].stop();之类的就可以控制了,还有一些其他控制都是类似,这里不作赘述。
上述内容如有错误,欢迎各位朋友加以指正,如有问题,也可互相探讨。