体验Flash MX(8):控制时钟Timer
新的闪烁世界按照每天一个类别的新特性来感受Flash MX的路已经走到了第八天,程序和设计的岔路口似隐似现的就在眼前,而我写这个系列的文章的目的是希望可以拉住要前往设计之路的同行说:“要不要试一试FlashMX?”,事实上我不过是想说——FlashMX,通往理性世界的后门。一个简单的程序基本流程需要包括:初始化,运行期,结束处理 三部分。当决定了一个程序的目的后,其3部分的内容也是多样的,不过少哪一部分都是无意义的。
在运行期的处理是通过一个主程序时钟来让程序一直处于循环状态,直到用户、异常错误或系统中断而退出循环到结束处理,而这个时钟即是我们今天要学习的一个单独课题。
早期的时钟(下面称Timer)很简单,直接取用CPU的运算速度并加以简单处理,直到高频率的CPU出现,人们才考虑如何处理/减少CPU间程序运行的差距。Flash 的时钟从版本 5的时代就已经看见改良后的效果,虽然在相差太大的机器上还是看到丢帧的问题,到Flash MX的今天,我们终于可以控制Timer了。
首先看一个放松点的例子:
createEmptyMovieClip("mc",1);
function drawDream() {
mc.lineStyle(random(++i/100),++i*random(30),(++i/30));
tempx=random(500);
tempy=10;
mc.moveTo(tempx,tempy);
mc.lineTo(tempx, tempy+300);
}
idDream=setInterval(drawDream,50);运用setInterval,每50毫秒执行一次drawDream,通过draw method随机绘制出来一个梦的窗帘……(看图1)
图1
升华升华……
//dream2
function drawDream() {
if(i==undefined){i=0;keynum=1;offy=300;clr=new Color(pic);}else if(i>=700) clearInterval (idDream);
mc.lineStyle(random(++i/i/10),++i*random(80),(i/50));
tempx+= i*2*keynum/10; //reverse set
keynum=tempx<250 ? 1 : -1; //reverse key
tempy=0;
offy-=.07;
mc.moveTo(tempx,tempy);
mc.lineTo(tempx, tempy+offy);
var tempcolor=clr.getTransform();
tempcolor.rb+=i/200; //color to sun
tempcolor.gb+=i/150; //color to leaf
clr.setTransform(tempcolor);
}//init
stage.scalemode="showall";
createEmptyMovieClip("pic",1);
createEmptyMovieClip("mc",2);
createEmptyMovieClip("loader",3);
pic.loadMovie("ice.jpg");
loader.onEnterFrame=function(){
if (_root.pic._width>0){
_root.pic._width=Stage.width;
_root.pic._height=Stage.height;
this.removeMovieClip();
}
}//init end
//start main timer
idDream=setInterval(drawDream,10);
新手先不要易做图,让我们一步步深入察看
第一步:产生我们Flash MX的初始化//init 到//init end部分,这段开始决定了屏幕的显示模式是拉伸式显示全部;接着产生我们需要的一切mc;产生以后读入一个jpg雪的图片,并附带一个读入的loader,当图片完全读入的时候设置图片的相应属性并“易做图”(自动踢出内存);
第二步,进入程序主循环。使用idDream来代表主循环timer 的id,并且每10毫秒刷新一次,这样就进入了内部子程序,里面也有自己的初始化、运行期、结束处理。
做光柱的算法我已经优化到这样子:
tempx+= i*2*keynum/10; //reverse set
keynum=tempx<250 ? 1 : -1; //reverse key状态每2次换一次,分别获得光柱当前划线的左右位置,而且通过keynum变量方便的设置中点,即250(随意一个什么位置)。
结合
mc.moveTo(tempx,tempy);
mc.lineTo(tempx, tempy+offy);即可画出一个光柱的模型,稍加处理即可得到下面的样子。(图2)
而所谓的光射的环境效果,我们可以简单尝试下面的算法:
var tempcolor=clr.getTransform();
tempcolor.rb+=i/200; //color to sun
tempcolor.gb+=i/150; //color to leaf
clr.setTransform(tempcolor);算法以速度为先,不考虑太多的客观因素,只按照程序当前的状态往太阳和绿色的生命感觉走(红色和绿色的增量补偿,rb要大于gb,否则没有光感)
最后就是结束条件:if(i>=700) clearInterval (idDream)。当程序运行了700/3次后,结束子程序,清除timer并返回主程序。
返回主程序后,无其他语句即保持静止状态,除非用户关闭窗口来结束程序。 可以测试一下效果,若觉得光感太强,可以调节rb和gb的值。(测试效果如图2)
图2
虽然setInterval不是系统级的,但这意味着在不使用movieclip的情况下来得到速度的提高的方法是良性进步,以后会有更多的程序使用timer而不用MovieClip,因为产生一个MovieClip的代价是继承了所有MovieClip的方法和属性,而Timer不过是一个Function或一个简单的Object,何乐而不为。
http://www.dnvs.net/tutorial/flash_mx/day8.exe
恶习不改破坏性测试:
//pic.loadMovie("ice.jpg");
loadMovie("ice.jpg",-1);
将第一条语句修改为第二条语句的样子,看看会发生什么?不管是测试环境还是直接运行swf,都会打开IE来读入刚刚我们需要读入的jpg,只要条件是负数……傻了眼,这回怎么去控制我要的jpg?
感谢DnVsystem