Smokefall
/**
* Copyright k__ ( http://wonderfl.net/user/k__ )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/mwNy
*/
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(10);
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,true,0x00ffffff)));
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 = 0xffffffff & Math.floor(Math.random() * 0xffffffff);
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) {
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 ++) {
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(2,2));
b.applyFilter(b,b.rect, new Point(0,0),
new ColorMatrixFilter([
0.96,0,0,0,
0,0.96,0,0,0,
0.0,0.96,0,0,
0,0,0,0.96,0]));
b.draw(brush,new Matrix,new ColorTransform,BlendMode.DARKEN);
}
private function lev(n:uint, lev:Number):uint {
var r:uint = Math.floor(((n >> 16) & 0x000ff) * lev);
var g:uint = Math.floor(((n >> 8) & 0x000ff) * lev);
var b:uint = Math.floor((n & 0x000ff) * lev);
return 0xff000000 | r << 16 | g << 8 | b
}
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
}
}
}