forked from: Rainfall

by jmbyh521 forked from Rainfall (diff: 1)
♥0 | Line 163 | Modified 2015-12-29 17:23:08 | MIT License
play

ActionScript3 source code

/**
 * Copyright jmbyh521 ( http://wonderfl.net/user/jmbyh521 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qQ9a
 */

// forked from k__'s Rainfall
package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.filters.*;
    
    public class Main extends Sprite {
        private var points:Array;
        private var nPoints:uint = 3000;
        private var obstacles:Array;
        private var nObstacles:uint =10;
        private var vp:Object;
        private var i:uint, j:uint, k:uint;
        private var cx:uint, cy:uint;
        private var canvas:Bitmap;
        private var r:Number = 0;
        private const FP:uint = 100;
        
        public function Main() {
            Wonderfl.capture_delay(20);
            cx = stage.stageWidth / 2;
            cy = stage.stageHeight / 2;
            vp = {x:0, y:150, z:- 200, rx:0, ry:0, rz:0}
            points = [];
            obstacles = [];
            
            var i:uint;
            
            for (i = 0; i < nObstacles; i ++) {
                obstacles.push(initObstacle({}));
            }
            addChild(canvas = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight,false,0x000000)));
            addEventListener(Event.ENTER_FRAME, h_enterframe);
        }
        
        private function initPoint(o:Object):Object {
            o.x = (Math.random() * 10 - 5 ) * 15;
            o.y = (Math.random() * 10 - 5) * 5;
            o.z = (Math.random() * 10 - 5) * 15;
            o.vx = (Math.random() - 0.5) / 6;
            o.vy = 1;
            o.vz = (Math.random() - 0.5) / 6;
            o.col = 0xff333333;
            o.trapped = false;
            o.drawFlag = false;
            return o;
        }
        
        
        private function initObstacle(o:Object):Object {
            o.x = (Math.random() * 10 - 5 ) * 15;
            o.y = (Math.random() * 10) * 10 + 50;
            o.z = (Math.random() * 10 - 5) * 15;
            o.w = Math.random()  * 50 +30;
            o.h = Math.random()  * 50 + 30;
            o.x -= o.w / 2;
            o.z -= o.h / 2;
            return o;
        }
        
        private function h_enterframe(evt:Event):void {
            if (points.length <= nPoints) {
                for(var i:uint = 0; i < 100; i ++) {
                points.push(initPoint({}));
                }
            }
            if (Math.random() < 0.01) {
                var ind:uint = Math.floor(obstacles.length * Math.random());
                initObstacle(obstacles[ind]);
            }
            r += 0.001;
            vp.x = Math.cos(r) * 200;
            vp.z = Math.sin(r) * 200;
            vp.ry = Math.atan2(vp.x, -vp.z);
            vp.rx =0.3;
            render();
        }
        
        private function render():void {
            var i:uint;
            for (i = 0; i < points.length; i ++) {
                move(points[i]);
            }
            var p2ds:Array = p3dTo2d(points);

            var brush:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);
            for (i = 0; i < p2ds.length; i ++) {
                if (p2ds[i].trapped) {
                     brush.setPixel32(p2ds[i].x + cx, p2ds[i].y + cy,0xff111111);
                } else {
                    brush.setPixel32(p2ds[i].x + cx, p2ds[i].y + cy,p2ds[i].col);
                }
            }
            var b:BitmapData = canvas.bitmapData;
            b.applyFilter(b,b.rect,new Point(0,0),new BlurFilter(0,2));
            
            b.applyFilter(b,b.rect, new Point(0,0),
            new ColorMatrixFilter([
                                  0.99,0,0,0,0,
                                  0,0.99,0,0,0,
                                  0.0,0.99,0,0,
                                  0,0,0,1,0]));
            
            b.draw(brush,new Matrix,new ColorTransform,BlendMode.ADD);
        }
        
        private function move(o:Object):void {
            var flag:Boolean = false;
            for (var i:uint = 0; i < obstacles.length; i ++) {
                if (obstacles[i].y >= o.y && obstacles[i].y <= o.y + o.vy) {
                    var rect:Rectangle = new Rectangle(obstacles[i].x, obstacles[i].z, obstacles[i].w, obstacles[i].h);
                    if (rect.contains(o.x, o.z)) {
                        o.y = obstacles[i].y;
                        flag = true;
                    }
                }
            }
            
            if (flag) {
                o.drawFlag = true;
                 if (!o.trapped) {
                    o.trapped =true;
                    var r:Number = Math.random() * Math.PI * 2;
                    var s:Number = (Math.random() + 1) / 10;
                    o.vx = Math.cos(r) * s;
                    o.vz = Math.sin(r) * s;
                    o.vy = 0;
                } 
            } else {
                o.trapped = false;
                o.vx = 0;
                o.vz = 0;
                o.vy += 0.01;
            }
            
            o.x += o.vx;
            o.y += o.vy;
            o.z += o.vz;
            
            if (o.y >= 200) {
                initPoint(o);
                //o.y = 0;
            }
            
        }
        
        private function p3dTo2d(p3ds:Array):Array {
            var i:uint;
            var p2ds:Array = [];
            
            //var p3ds2:Array = [];
            var rxs:Number = Math.sin(vp.rx);
            var rxc:Number = Math.cos(vp.rx);
            var rys:Number = Math.sin(vp.ry);
            var ryc:Number = Math.cos(vp.ry);
            var rzs:Number = Math.sin(vp.rz);
            var rzc:Number = Math.cos(vp.rz);
            
            for (i = 0; i < p3ds.length; i ++) {
                var to:Object = {}, tto:Object = {};
                tto.x = p3ds[i].x - vp.x;
                tto.y = p3ds[i].y - vp.y;
                tto.z = p3ds[i].z - vp.z;
                
                to = {x:tto.x, y:tto.y, z:tto.z};
                var tx:Number,ty:Number,tz:Number;
                
                
                tx = to.x; ty = to.y;
                to.x =  rzc * tx + rzs * ty;
                to.y =  rzc * ty - rzs * tx;
                
                tx = to.x; tz = to.z;
                to.x =  ryc * tx + rys * tz;
                to.z =  ryc * tz - rys * tx;
                
                ty = to.y; tz = to.z;
                to.y =  rxc * ty + rxs * tz;
                to.z =  rxc * tz - rxs * ty;
                
                if (i == 0) {
                    //trace(Math.floor(to.x), Math.floor(to.y), Math.floor(to.z));
                }
                if (to.z  >= FP) {
                    var ratio:Number = (to.z + FP) / FP;
                    p2ds.push({x:to.x * ratio, y:to.y * ratio, z:to.z, col:p3ds[i].col,drawFlag:p3ds[i].drawFlag, trapped:p3ds[i].trapped});
                }
            }
            return p2ds
        }
        
    }
}