/**
* Copyright bongiovi015 ( http://wonderfl.net/user/bongiovi015 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4wbg
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Shader;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.ShaderFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.ByteArray;
[SWF(width=465, height=465, frameRate=30, backgroundColor=0)]
public class WormImage extends Sprite {
public static const CONTRAST : Number = 1.5;
public static const SCALE : Number = 4;
public static const MIN_NUM_PARTICLE : uint = 200;
public static const NUM_RENDER : int = 20;
public var loaderImage : Loader = new Loader;
public var loaderShader : URLLoader = new URLLoader;
public var shader : Shader = new Shader;
private var bmpOrg:Bitmap;
private var bmpd:BitmapData;
private var bmpdRock:BitmapData;
private var bmpdOrg:BitmapData;
private var canvas:BitmapData;
private var W:int;
private var H:int;
private var particles:Array;
private var _tf:TextField;
public function WormImage() {
graphics.beginFill(0);
graphics.drawRect(0, 0, 465, 465);
graphics.endFill();
_tf = new TextField();
_tf.autoSize = "left";
addChild(_tf);
var format:TextFormat = new TextFormat("Arial", 12, 0xFFFFFF);
_tf.defaultTextFormat = format;
_tf.text = "Loading Image";
loaderImage.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
loaderImage.load(new URLRequest("http://www.bongiovi.tw/wonderfl/rock465.jpg"), new LoaderContext(true));
}
private function imgLoaded(e:Event) : void {
_tf.text = "Loading Shader";
bmpOrg = Bitmap(loaderImage.content);
loaderShader.addEventListener(Event.COMPLETE, shaderLoaded);
loaderShader.dataFormat = URLLoaderDataFormat.BINARY;
loaderShader.load(new URLRequest("http://www.bongiovi.tw/wonderfl/worm.pbj"));
}
private function shaderLoaded(e:Event) : void {
_tf.text = " ";
shader.byteCode = ByteArray(loaderShader.data);
bmpdRock = bmpOrg.bitmapData.clone();
bmpdOrg = bmpOrg.bitmapData;
shader.data.contrast.value = [CONTRAST];
var filter:ShaderFilter = new ShaderFilter(shader);
bmpdRock.applyFilter(bmpdRock, bmpdRock.rect, new Point, filter);
W = bmpdRock.width * SCALE;
H = bmpdRock.height * SCALE;
var mtx:Matrix = new Matrix();
mtx.scale(SCALE, SCALE);
bmpd = new BitmapData(W,H);
bmpd.draw(bmpdRock, mtx);
canvas = new BitmapData(W, H, true, 0);
var bmp:Bitmap = Bitmap(addChild(new Bitmap(canvas)));
bmp.scaleX = bmp.scaleY = 1/SCALE;
bmp.smoothing = true;
particles = [];
addEventListener(Event.ENTER_FRAME, _loop);
}
private function _loop(e:Event) : void {
var i:int = 0;
while(i++<NUM_RENDER) render();
}
public function render() : void {
var speed:Number = 1;
for each (var p:Particle in particles) {
p.render(bmpd.getPixel(p.x, p.y));
if(p.x < 0 || p.x >= W || p.y < 0 || p.y >= H || p.life < 0) particles.splice(particles.indexOf(p));
else {
_drawPixel(p.x, p.y, p.color);
}
}
while(particles.length <= MIN_NUM_PARTICLE) _spwan();
}
private function _drawPixel(x:Number, y:Number, fillColor:uint) : void {
var o:Object = getARGB(canvas.getPixel32(x, y));
var add:Number = 0;
add = o.a == 0 ? 100 : 20;
o.a += add;
if(o.a > 255) o.a = 255;
var color:uint = o.a << 24 | fillColor;
canvas.setPixel32(x, y, color);
}
private function _spwan(e:Event=null) : void {
var p:Particle = new Particle();
var numTries:int;
if(e == null) {
p.x = Math.random() * W;
p.y = Math.random() * H;
}else {
p.x = Particle(e.currentTarget).x;
p.y = Particle(e.currentTarget).y;
}
p.color = bmpdOrg.getPixel(p.x/SCALE, p.y/SCALE);
particles.push(p);
p.addEventListener(Particle.SPWAN, _spwan);
}
public static function getARGB(pixelValue:Number) : Object {
var alphaValue:uint = pixelValue >> 24 & 0xFF;
var red:uint = pixelValue >> 16 & 0xFF;
var green:uint = pixelValue >> 8 & 0xFF;
var blue:uint = pixelValue & 0xFF;
return {a:alphaValue, r:red, g:green, b:blue};
}
}
}
import flash.events.Event;
import flash.events.EventDispatcher;
class Particle extends EventDispatcher {
public static const SPWAN : String = "onSpwan";
public static const SPWAN_AMOUNT : int = 5;
public static const SPWAN_GAP : int = 20;
public static const STEERING_FACTOR : Number = .7;
public static const ROTATE_AMOUNT : Number = .05;
public static const BRIGHTNESS_OFFSET : int = 3;
public static const LIFE_SCALE : Number = 100;
public static const MAX_LIFE : int = 500;
public var v:Vector2D;
public var x:Number;
public var y:Number;
public var life:int;
public var color:uint;
private var _spwanCount:int;
public function Particle() {
x = y = 0;
v = new Vector2D();
v.length = 1;
v.angle = Math.random() * Math.PI * 2;
life = 0;
_spwanCount = 0;
}
public function render(color:uint) : void {
if(Math.random() > STEERING_FACTOR) v.angle += random(-ROTATE_AMOUNT, ROTATE_AMOUNT);
x += v.x;
y += v.y;
var br:Number = lengthOfColor(color);
br = Math.floor(br * 10) - BRIGHTNESS_OFFSET;
if(br>0) br *= LIFE_SCALE;
else if(br<0) br = -1;
life += br;
if(life >= MAX_LIFE) {
_spwanCount ++;
if( _spwanCount >= SPWAN_GAP) {
_spwanCount = 0;
var i:int = 0;
while(i++ < SPWAN_AMOUNT ) dispatchEvent(new Event(SPWAN));
}
} else {
_spwanCount --;
if(_spwanCount < 0) _spwanCount = 0;
}
}
public static function random(min:Number, max:Number) : Number { return min + Math.random() * ( max - min); }
public static const MAX_COLOR_LENGTH :int = 255*255*3;
public static function lengthOfColor(color:uint) : Number {
var o:Object = getRGB(color);
return (o.r * o.r + o.g * o.g + o.b * o.b) / MAX_COLOR_LENGTH;
}
public static function getRGB(pixelValue:uint) : Object {
var red:uint = pixelValue >> 16 & 0xFF;
var green:uint = pixelValue >> 8 & 0xFF;
var blue:uint = pixelValue & 0xFF;
return {r:red, g:green, b:blue};
}
}
import flash.display.Graphics;
/**
* A basic 2-dimensional vector class.
*/
class Vector2D {
private var _x:Number;
private var _y:Number;
/**
* Constructor.
*/
public function Vector2D(x:Number = 0, y:Number = 0) {
_x=x;
_y=y;
}
/**
* Can be used to visualize the vector. Generally used for debug purposes only.
* @param graphics The Graphics instance to draw the vector on.
* @param color The color of the line used to represent the vector.
*/
public function draw(graphics:Graphics, color:uint = 0):void {
graphics.lineStyle(0, color);
graphics.moveTo(0, 0);
graphics.lineTo(_x, _y);
}
/**
* Generates a copy of this vector.
* @return Vector2D A copy of this vector.
*/
public function clone():Vector2D {
return new Vector2D(x, y);
}
/**
* Sets this vector's x and y values, and thus length, to zero.
* @return Vector2D A reference to this vector.
*/
public function zero():Vector2D {
_x=0;
_y=0;
return this;
}
/**
* Whether or not this vector is equal to zero, i.e. its x, y, and length are zero.
* @return Boolean True if vector is zero, otherwise false.
*/
public function isZero():Boolean {
return _x == 0 && _y == 0;
}
/**
* Sets / gets the length or magnitude of this vector. Changing the length will change the x and y
but not the angle of this vector.
*/
public function set length(value:Number):void {
var a:Number=angle;
_x=Math.cos(a)*value;
_y=Math.sin(a)*value;
}
public function get length():Number {
return Math.sqrt(lengthSQ);
}
/**
* Gets the length of this vector, squared.
*/
public function get lengthSQ():Number {
return _x * _x + _y * _y;
}
/**
* Gets / sets the angle of this vector. Changing the angle changes the x and y but retains the
same length.
*/
public function set angle(value:Number):void {
var len:Number=length;
_x=Math.cos(value)*len;
_y=Math.sin(value)*len;
}
public function get angle():Number {
return Math.atan2(_y, _x);
}
/**
* Normalizes this vector. Equivalent to setting the length to one, but more efficient.
* @return Vector2D A reference to this vector.
*/
public function normalize():Vector2D {
if (length==0) {
_x=1;
return this;
}
var len:Number=length;
_x/=len;
_y/=len;
return this;
}
/**
* Ensures the length of the vector is no longer than the given value.
* @param max The maximum value this vector should be. If length is larger than max, it will be
truncated to this value.
* @return Vector2D A reference to this vector.
*/
public function truncate(max:Number):Vector2D {
length=Math.min(max,length);
return this;
}
/**
* Reverses the direction of this vector.
* @return Vector2D A reference to this vector.
*/
public function reverse():Vector2D {
_x=- _x;
_y=- _y;
return this;
}
/**
* Whether or not this vector is normalized, i.e. its length is equal to one.
* @return Boolean True if length is one, otherwise false.
*/
public function isNormalized():Boolean {
return length == 1.0;
}
/**
* Calculates the dot product of this vector and another given vector.
* @param v2 Another Vector2D instance.
* @return Number The dot product of this vector and the one passed in as a parameter.
*/
public function dotProd(v2:Vector2D):Number {
return _x * v2.x + _y * v2.y;
}
/**
* Calculates the cross product of this vector and another given vector.
* @param v2 Another Vector2D instance.
* @return Number The cross product of this vector and the one passed in as a parameter.
*/
public function crossProd(v2:Vector2D):Number {
return _x * v2.y - _y * v2.x;
}
/**
* Calculates the angle between two vectors.
* @param v1 The first Vector2D instance.
* @param v2 The second Vector2D instance.
* @return Number the angle between the two given vectors.
*/
public static function angleBetween(v1:Vector2D, v2:Vector2D):Number {
if (! v1.isNormalized()) {
v1=v1.clone().normalize();
}
if (! v2.isNormalized()) {
v2=v2.clone().normalize();
}
return Math.acos(v1.dotProd(v2));
}
/**
* Determines if a given vector is to the right or left of this vector.
* @return int If to the left, returns -1. If to the right, +1.
*/
public function sign(v2:Vector2D):int {
return perp.dotProd(v2) < 0 ? -1 : 1;
}
/**
* Finds a vector that is perpendicular to this vector.
* @return Vector2D A vector that is perpendicular to this vector.
*/
public function get perp():Vector2D {
return new Vector2D(-y, x);
}
/**
* Calculates the distance from this vector to another given vector.
* @param v2 A Vector2D instance.
* @return Number The distance from this vector to the vector passed as a parameter.
*/
public function dist(v2:Vector2D):Number {
return Math.sqrt(distSQ(v2));
}
/**
* Calculates the distance squared from this vector to another given vector.
* @param v2 A Vector2D instance.
* @return Number The distance squared from this vector to the vector passed as a parameter.
*/
public function distSQ(v2:Vector2D):Number {
var dx:Number=v2.x-x;
var dy:Number=v2.y-y;
return dx * dx + dy * dy;
}
/**
* Adds a vector to this vector, creating a new Vector2D instance to hold the result.
* @param v2 A Vector2D instance.
* @return Vector2D A new vector containing the results of the addition.
*/
public function add(v2:Vector2D):Vector2D {
return new Vector2D(_x + v2.x, _y + v2.y);
}
/**
* Subtacts a vector to this vector, creating a new Vector2D instance to hold the result.
* @param v2 A Vector2D instance.
* @return Vector2D A new vector containing the results of the subtraction.
*/
public function subtract(v2:Vector2D):Vector2D {
return new Vector2D(_x - v2.x, _y - v2.y);
}
/**
* Multiplies this vector by a value, creating a new Vector2D instance to hold the result.
* @param v2 A Vector2D instance.
* @return Vector2D A new vector containing the results of the multiplication.
*/
public function multiply(value:Number):Vector2D {
return new Vector2D(_x * value, _y * value);
}
/**
* Divides this vector by a value, creating a new Vector2D instance to hold the result.
* @param v2 A Vector2D instance.
* @return Vector2D A new vector containing the results of the division.
*/
public function divide(value:Number):Vector2D {
return new Vector2D(_x / value, _y / value);
}
/**
* Indicates whether this vector and another Vector2D instance are equal in value.
* @param v2 A Vector2D instance.
* @return Boolean True if the other vector is equal to this one, false if not.
*/
public function equals(v2:Vector2D):Boolean {
return _x == v2.x && _y == v2.y;
}
/**
* Sets / gets the x value of this vector.
*/
public function set x(value:Number):void {
_x=value;
}
public function get x():Number {
return _x;
}
/**
* Sets / gets the y value of this vector.
*/
public function set y(value:Number):void {
_y=value;
}
public function get y():Number {
return _y;
}
/**
* Generates a string representation of this vector.
* @return String A description of this vector.
*/
public function toString():String {
return "[Vector2D (x:" + _x + ", y:" + _y + ")]";
}
}