KCDDP ADV综合创作站 » 技术发布区 » 下雨下雪插件的改造版


2007-6-12 11:14 karryngai
下雨下雪插件的改造版

说是改造,其实是重写了一次,除了方法相似外,已经被写得面目全非了
加入了速度,纵向偏移度几个概念,还有雨或雪从疏到密或从密到疏所经历的时间,使得原插件中雨粒或雪粒的消失变得自然一点
其实可以写得更好的,但是从疏到密的过程涉及一道很冗长的概率公式,还要积分的说,懒得去想怎样去用函数逼近它了,直接取个认为还过得去的函数轻松搞掂= =
直考虑在其中加入风的概念,风会让雨或雪摆动起来,有空的话再作改造

2007-6-12 11:16 karryngai
[code]
;by karryngai 2007.6.8

@if exp="typeof(global.rain_object)=='undefined'"
@iscript

class RainGrain{
        var window,owner;
        var back,fore;
        var x,y;
        var xvelo,yvelo;               
        var appear;
        var constant1,constant2;

        function RainGrain(window,owner,percent){
                this.window=window;
                this.owner=owner;               
       
                var piccount=0;
                for(var i=0;;i++){
                        if(Storages.isExistentStorage("rain_"+i+".png"))
                                piccount++;
                        else
                                break;
                }
                       
                back=new Layer(window,window.primaryLayer);
                fore=new Layer(window,window.primaryLayer);
                fore.absolute=back.absolute=2000000-1;
               
                back.loadImages("rain_"+intrandom(0,piccount-1));
                fore.assignImages(back);
                       
                back.setSizeToImageSize();
                fore.setSizeToImageSize();
                var h=int(back.height*percent);
                fore.height=back.height=h;
                fore.imageTop=back.imageTop=h-back.height;
                       
                fore.hitType=back.hitType=htMask;
                fore.hitThreshold=back.hitThreshold=256;
                       
                x=int(window.primaryLayer.width*Math.random());
                y=-back.height;
                back.setPos(x,y);
                fore.setPos(x,y);

                back.opacity=155+int(100*Math.random());
                fore.opacity=155+int(100*Math.random());
                       
                xvelo=0;
                yvelo=int(back.height/5+owner.excursion*2*Math.random());

                appear=false;

                constant1=1.0/(owner.starttime/owner.interval)/4.0;
                constant2=1.0/(owner.stoptime/owner.interval)*8.0;
        }

        function setAppear(){
                appear=true;
                back.visible=owner.backVisible;
                fore.visible=owner.foreVisible;
        }

        function setDisappear(){
                appear=false;
                back.visible=false;
                fore.visible=false;
        }

        function setVisible(){
                if(appear){
                        back.visible=owner.backVisible;
                        fore.visible=owner.foreVisible;
                }
                else{
                        back.visible=false;
                        fore.visible=false;
                }
        }

        function setPosition(){
                if(owner.start){
                        if(!appear)
                                setAppear() if Math.random()<constant1;
                        else{
                                x+=xvelo;
                                y+=yvelo;
                                if(y>=window.primaryLayer.height){
                                        x=int(window.primaryLayer.width*Math.random());       
                                        y=-int(back.height*Math.random());
                                }
                                back.setPos(x,y);
                                fore.setPos(x,y);
                        }
                }
                else{
                        if(appear)
                                setDisappear() if Math.random()<constant2;
                        if(appear){                       
                                x+=xvelo;
                                y+=yvelo;
                                if(y>=window.primaryLayer.height){
                                        x=int(window.primaryLayer.width*Math.random());       
                                        y=-int(back.height*Math.random());
                                }
                                back.setPos(x,y);
                                fore.setPos(x,y);
                        }
                }               
        }

        function exchangeForeBack(){
                var temp;
                temp=back;
                back=fore;
                fore=temp;
        }

        function finalize(){
                invalidate back;
                invalidate fore;
        }

}

class RainPlugin extends KAGPlugin{
        var window;
        var count;
        var backVisible,foreVisible;
        var excursion;
        var raingrain=[];
        var timer,interval,speed;
        var start;
        var starttime,stoptime;

        function RainPlugin(win){
                super.KAGPlugin(...);
                window=win;
        }

        function startRain(elm){
                if(timer!==void) return;
               
                count=300;
                foreVisible=backVisible=true;
                excursion=25;
                interval=50;
                speed=50;
                starttime=10000;
                stoptime=1000;
                setOption(elm);       

                for(var i=0;i<count;i++){
                        var percent=intrandom(50,100)/100.0;
                        raingrain[i]=new RainGrain(window,this,percent);
                }

                start=true;
                timer=new Timer(timeevent,"");
                timer.enabled=true;
                timer.interval=interval;
        }

        function timeevent(){
                for(var i=0;i<count;i++)
                        raingrain[i].setPosition();
                if(!start){
                        stoptime-=interval;
                        if(stoptime<0)
                                invalidateRain();
                }
       
        }               

        function setOption(elm){
                count=elm.count if elm.count!==void;
                backVisible=elm.backvisible if elm.backvisible!==void;
                foreVisible=elm.forevisible if elm.forevisible!==void;
                if(elm.excursion!==void){
                        if(elm.excursion>200)
                                excursion=200;
                        else if(elm.excursion<0)
                                excursion=0;
                        else
                                excursion=elm.excursion;
                }
                if(elm.speed!==void){
                        speed=elm.speed;
                        if(speed<0)
                                speed=0;
                        if(elm.speed>=100)
                                speed=99;
                        interval=100-speed;
                }
                if(elm.starttime!==void){
                        if(elm.starttime<100)
                                starttime=100;
                        else
                                starttime=elm.starttime;
                }
                if(elm.stoptime!==void){
                        if(elm.stoptime<100)
                                stoptime=100;
                        else
                                stoptime=elm.stoptime;
                }
        }       
       
        function stopRain(elm){
                if(timer===void) return;
                if(elm.stoptime!==void){
                        if(elm.stoptime<100)
                                stoptime=100;
                        else
                                stoptime=elm.stoptime;
                }
                start=false;
        }

        function invalidateRain(){
                for(var i=0;i<raingrain.count;i++)
                        invalidate raingrain[i];
                raingrain.count=0;
                invalidate timer;
                timer=void;
        }

        function finalize(){
                super.finalize();
                for(var i=0;i<raingrain.count;i++)
                        invalidate raingrain[i];
                invalidate raingrain;
                invalidate timer if timer!==void;
        }

        function onStore(f,elm){
                super.onStore(...);
                f.rain=%[];
                f.rain.israining=(timer!==void);
                f.rain.backvisible=backVisible;
                f.rain.forevisible=foreVisible;
                f.rain.excursion=excursion;
                f.rain.count=count;
                f.rain.speed=speed;
                f.rain.starttime=starttime;
                f.rain.stoptime=stoptime;
                stopRain(f.rain) if timer!=void;
        }

        function onRestore(f,clear,elm){
                super.onRestore(...);
                f.rain.starttime/=3;
                if(f.rain.israining)
                        startRain(f.rain);
                delete f.rain;

        }

        function onCopyLayer(toback){
                super.onCopyLayer(...);
                if(toback)
                        backVisible=foreVisible;
                else
                        foreVisible=backVisible;
               
                for(var i=0;i<raingrain.count;i++)
                        rainggrain[i].setVisible();
        }

        function onExchangeForeBack(){
                super.onExchangeForeBack();
                for(var i=0;i<raingrain.count;i++)
                        raingrain[i].exchangeForeBack();               
        }                               

}
kag.addPlugin(global.rain_object=new RainPlugin(kag));

@endscript
@endif

@macro name=startrain
@eval exp="global.rain_object.startRain(mp)"
@endmacro

@macro name=stoprain
@eval exp="global.rain_object.stopRain(mp)"
@endmacro

@macro name=saverain
@eval exp="global.rain_object.onStore(f,'tempsave')"
@endmacro

@macro name=loadrain
@eval exp="global.rain_object.onRestore(f,false,'tempload')"
@endmacro

@return
[/code]

@startrain  backvisible=true forevisible=true count=100 excursion=50 starttime=2000 stoptime=1000 speed=50
backvisible         雨粒里层的可视性
forevisible         雨粒表层的可视性
count                雨粒的数目,数目越大,所需内存空间越大
excursion        雨粒纵向移动的偏离位置,可填0到100
starttime        雨粒从疏到密所经历的时间,单位是毫秒(只是一个估计的值)
stoptime        雨粒停止时从密到疏所经历的时间,单位是毫秒(只是一个估计的值)
speed                雨粒的速度,可填0到100

@stoprain stoptime=4000
stoptime        雨粒停止时从密到疏所经历的时间,单位是毫秒(只是一个估计的值),在startrain中设定了,在这里可以不用设定

@saverain        如果使用右键菜单时,需对现在的下雨状态进行保存,保存的同时也会让雨停止,停止所需的时间来源于startrain的stoptime

@loadrain        读取保存的雨状态,让雨粒重现

在使用这个插件时,请把确认雨粒图像的命名方式,必须是rain_X.png,X是0以上的整数,可自行放入任意张雨粒图像,但X必须是从0开始的连续数字
如rain_0.png,rain_1.png,rain_2.png,rain_3.png......

2007-6-12 11:17 karryngai
[code]
;by karryngai 2007.6.10

@if exp="typeof(global.snow_object)=='undefined'""
@iscript

class SnowGrain{
        var window,owner;
        var back,fore;
        var x,y;
        var xvelo,yvelo;
        var xaccel;
        var appear;
        var constant1,constant2;

        function SnowGrain(window,owner){
                this.window=window;       
                this.owner=owner;               
       
                var piccount=0;
                for(var i=0;;i++){
                        if(Storages.isExistentStorage("snow_"+i+".png"))
                                piccount++;
                        else
                                break;
                }

                back=new Layer(window,window.primaryLayer);
                fore=new Layer(window,window.primaryLayer);
                fore.absolute=back.absolute=2000000-1;

                back.loadImages("snow_"+intrandom(0,piccount-1));
                fore.assignImages(back);

                back.setSizeToImageSize();
                fore.setSizeToImageSize();
       
                x=int(window.primaryLayer.width*Math.random());
                y=-back.height;
                back.setPos(x,y);
                fore.setPos(x,y);

                back.opacity=int(155+100*Math.random());
                fore.opacity=int(155+100*Math.random());

                xvelo=0;
                yvelo=(back.height-6)/4+2+Math.random()*owner.excursion/5;
                xaccel=Math.random()*owner.accel/10;

                appear=false;

                constant1=1.0/(owner.starttime/owner.interval)/4.0;
                constant2=1.0/(owner.stoptime/owner.interval)*8.0;                               
        }

        function setAppear(){
                appear=true;
                back.visible=owner.backVisible;
                fore.visible=owner.foreVisible;
        }

        function setDisappear(){
                appear=false;
                back.visible=false;
                fore.visible=false;
        }

        function setVisible(){
                if(appear){
                        back.visible=owner.backVisible;
                        fore.visible=owner.foreVisible;       
                }
                else{
                        back.visible=false;
                        fore.visible=false;
                }
        }

        function setPosition(){
                if(owner.start){
                        if(!appear)
                                setAppear() if Math.random()<constant1;
                        else{
                                x+=xvelo;
                                y+=yvelo;
                               
                                var ceil=0.15*owner.accel;
                                xvelo+=xaccel;
                                if(xvelo>ceil)
                                        xvelo=ceil;
                                if(xvelo<-ceil)
                                        xvelo=-ceil;

                                var ceil=0.02*owner.accel;
                                xaccel+=(Math.random()-0.5)*owner.accel*0.03;
                                if(xaccel>ceil)
                                        xaccel=ceil;
                                if(xaccel<-ceil)
                                        xaccel=-ceil;
                               
                                if(y>window.primaryLayer.height){
                                        x=int(window.primaryLayer.width*Math.random());
                                        y=-back.height;
                                }

                                back.setPos(x,y);
                                fore.setPos(x,y);
                        }
                }
                else{
                        if(appear)
                                setDisappear() if Math.random()<constant2;
                        if(appear){
                                x+=xvelo;
                                y+=yvelo;
                               
                                var ceil=0.15*owner.accel;
                                xvelo+=xaccel;
                                if(xvelo>ceil)
                                        xvelo=ceil;
                                if(xvelo<-ceil)
                                        xvelo=-ceil;

                                var ceil=0.02*owner.accel;
                                xaccel+=(Math.random()-0.5)*owner.accel*0.03;
                                if(xaccel>ceil)
                                        xaccel=ceil;
                                if(xaccel<-ceil)
                                        xaccel=-ceil;
                               
                                if(y>window.primaryLayer.height){
                                        x=int(window.primaryLayer.width*Math.random());
                                        y=-back.height;
                                }

                                back.setPos(x,y);
                                fore.setPos(x,y);
                        }
                }                                       
               
        }

        function exchangeForeBack(){
                var temp;
                temp=back;
                back=fore;
                fore=temp;
        }
        function finalize(){
                invalidate back;
                invalidate fore;
        }

}


class SnowPlugin extends KAGPlugin{
        var window;
        var count;
        var backVisible,foreVisible;
        var snowgrain=[];
        var timer,interval,speed;
        var excursion,accel;
        var start;
        var starttime,stoptime;

        function SnowPlugin(window){
                super.KAGPlugin(window);
                this.window=window;
        }

        function startSnow(elm){
                if(timer!==void) return;               

                count=300;       
                foreVisible=backVisible=true;
                interval=50;               
                speed=50;
                excursion=50;
                accel=10;
                starttime=10000;
                stoptime=1000;
                setOption(elm);       

                for(var i=0;i<count;i++)
                        snowgrain[i]=new SnowGrain(window,this);       

                start=true;

                timer=new Timer(timeevent,"");
                timer.enabled=true;
                timer.interval=interval;                       
        }

        function timeevent(){
                for(var i=0;i<count;i++)
                        snowgrain[i].setPosition();
                if(!start){
                        stoptime-=interval;
                        if(stoptime<0)
                                invalidateSnow();       
                }       
        }

        function setOption(elm){
                count=elm.count if elm.count!==void;
                backVisible=elm.backvisible if elm.backvisible!==void;
                foreVisible=elm.forevisible if elm.forevisible!==void;
                if(elm.excursion!==void){
                        if(elm.excursion>200)
                                excursion=200;
                        else if(elm.excursion<0)
                                excursion=0;
                        else
                                excursion=elm.excursion;
                }
                if(elm.accel!==void){
                        if(elm.accel>100)
                                accel=100;
                        else if(elm.accel<0)
                                accel=0;
                        else
                                accel=elm.accel;
                }
                if(elm.speed!==void){
                        speed=elm.speed;
                        if(speed<0)
                                speed=0;
                        if(elm.speed>=100)
                                speed=99;
                        interval=100-speed;
                }
                if(elm.starttime!==void){
                        if(elm.starttime<100)
                                starttime=100;
                        else
                                starttime=elm.starttime;
                }
                if(elm.stoptime!==void){
                        if(elm.stoptime<100)
                                stoptime=100;
                        else
                                stoptime=elm.stoptime;
                }               
        }

        function stopSnow(elm){
                if(timer==void) return;
                if(elm.stoptime!==void){
                        if(elm.stoptime<100)
                                stoptime=100;
                        else
                                stoptime=elm.stoptime;
                }
                start=false;
        }

        function invalidateSnow(){
                for(var i=0;i<snowgrain.count;i++)
                        invalidate snowgrain[i];
                snowgrain.count=0;
                invalidate timer;
                timer=void;
        }

        function finalize(){
                super.finalize();
                for(var i=0;i<snowgrain.count;i++)
                        invalidate snowgrain[i];
                invalidate snowgrain;
                invalidate timer if timer!==void;
        }

        function onStore(f,elm){
                super.onStore(...);
                f.snow=%[];
                f.snow.issnowing=(timer!==void);
                f.snow.count=count;
                f.snow.backvisible=backVisible;
                f.snow.forevisible=foreVisible;
                f.snow.excursion=excursion;
                f.snow.accel=accel;
                f.snow.speed=speed;
                f.snow.starttime=starttime;
                f.snow.stoptime=stoptime;
                stopSnow(f) if timer!==void;
        }               
                                               
        function onRestore(f,clear,elm){
                super.onRestore(...);
                f.snow.starttime/=3;
                if(f.snow.issnowing)
                        startSnow(f.snow);
                delete f.snow;
        }

        function onCopyLayer(toback){
                super.onCopyLayer(...);
                if(toback)
                        backVisible=foreVisible;
                else
                        foreVisible=backVisible;
                for(var i=0;i<snowgrain.count;i++)
                        snowgrain[i].setVisible();
        }

        function onExchangeForeBack(){
                super.onExchangeForeBack();
                for(var i=0;i<snowgrain.count;i++)
                        snowgrain[i].exchangeForeBack();               
        }       
}

kag.addPlugin(global.snow_object=new SnowPlugin(kag));

@endscript
@endif

@macro name=startsnow
@eval exp="global.snow_object.startSnow(mp)"
@endmacro

@macro name=stopsnow
@eval exp="global.snow_object.stopSnow(mp)"
@endmacro

@macro name=savesnow
@eval exp="global.snow_object.onStore(f,'tempsave')"
@endmacro

@macro name=loadsnow
@eval exp="global.snow_object.onRestore(f,false,'tempload')"
@endmacro

@return

[/code]

@startsnow  backvisible=true forevisible=true count=100 excursion=50 starttime=2000 stoptime=1000 speed=50 accel=20
backvisible         雪粒里层的可视性
forevisible         雪粒表层的可视性
count                雪粒的数目,注意数目越大,所占内存空间越大
excursion        雪粒纵向移动的偏离位置,可填0到100
starttime        雪粒从疏到密所经历的时间,单位是毫秒(只是一个估计的值)
stoptime        雪粒停止时从密到疏所经历的时间,单位是毫秒(只是一个估计的值)
speed                雪粒的速度,可填0到100
accel                雪粒横向的加速度,可填0到100

@stopsnow stoptime=4000
stoptime        雪粒停止时从密到疏所经历的时间,单位是毫秒(只是一个估计的值),在startsnow中设定了,在这里可以不用设定

@savesnow        如果使用右键菜单时,需对现在的下雪状态进行保存,保存的同时也会让雪停止,停止所需的时间来源于startsnow的stoptime

@loadsnow        读取保存的雪状态,让雪粒重现

在使用这个插件时,请把确认雪粒图像的命名方式,必须是snow_X.png,X是0以上的整数,可自行放入任意张雪粒图像,但X必须是从0开始的连续数字
如snow_0.png,snow_1.png,snow_2.png,snow_3.png......

2007-6-12 11:25 karryngai
话说,tjs的除错功能太差了...写snow插件时,偶不小心把intrandom打成了random...但是因为迷乱了心窍,看不出错在哪里...系统又不说错在哪里...结果花去了偶半个小时的时间才找出了错误...
以上插件已经过多次试验,应该没问题...如有问题...请指正...

2007-6-12 13:32 Miliardo
呵呵,Debug的话,要多利用控制台和程序内的楔子才行= v =
你大概是还没有适应吧= v =

2007-12-24 22:15 sarah707
有关于这个插件……在使用的时候出了一点问题……下雨的插件在backvisible和forevisible都true的情况下一trans就会没有……请问下这个是bug还是本来就是这样写的呢?
我把back和fore改成
back=new Layer(window,window.back.base);
fore=new Layer(window,window.fore.base);
就可以正常trans,目前还没发现什么问题……
另外,有一处笔误,268行raingrain写成了rainggrain

[[i] 本帖最后由 sarah707 于 2007-12-24 22:52 编辑 [/i]]

2008-3-14 12:27 dantelight
很小白地问一下哦。。。
我按照那个插件使用说明的使用这个插件
为什么每次调用时都显示找不到成员startSnow...?
555...
可以用了。。。原来换到system才行啊。。。

[[i] 本帖最后由 dantelight 于 2008-3-14 18:50 编辑 [/i]]

2008-8-3 19:08 darkcross
那么,如何设定图层呢?谢谢!

2008-9-20 16:15 sakuyuki
遇到了和dantelight一样的问题,
‘无法找到成员 "startSnow"  at anonymous@0x093459F8(1)[(top level script) global]……’
而且就算是换到SYSTEM也不行……怎么办?

页: [1]
查看完整版本: 下雨下雪插件的改造版


Powered by Discuz! Archiver 5.5.0  © 2001-2006 Comsenz Inc.