forked from: forked from: Marimo

by mtok forked from forked from: Marimo (diff: 289)
...
@author ...
♥0 | Line 201 | Modified 2009-10-23 02:23:20 | MIT License
play

ActionScript3 source code

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

package  
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author ...
	 */
	public class FluffBallTest extends Sprite
	{
		private var ball1:FluffBall;
		private var _bmps:Vector.<Bitmap>;
		private var _interval:Number = 40;
		public function FluffBallTest() 
		{
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		}
		
		private function addedToStageHandler(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			var director:FluffBallDirector = new FluffBallDirector();
			director.bodyRadius = 40;
			director.quality = 60;
			var builder:FluffBallBuilder = new FluffBallBuilder();
			
			ball1 = director.build(builder);
			
			var r:Rectangle = ball1.getBounds(this); 
			var bd:BitmapData = new BitmapData(r.width, r.height, true, 0x00ff00ff);
			bd.draw(ball1, new Matrix(1, 0, 0, 1, -r.x, -r.y));
			var bmp:Bitmap, bmpTmp:Bitmap;
			bmp = new Bitmap(bd);
			addChild(bmp);
			bmp.x = stage.stageWidth * 0.5;
			bmp.y = stage.stageHeight * 0.5;

			_bmps = new Vector.<Bitmap>();
			_bmps.push(bmp);
			bmpTmp = bmp;
			for (var i:int = 1; i < 1; i++) {
				bmp = new Bitmap(bd);
				bmp.x = bmpTmp.x;
				bmp.y = bmpTmp.y - _interval;
				_bmps.push(bmp);
				addChild(bmp);
				bmpTmp = bmp;
			}
			
		}
		
	}

}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Vector3D;
import flash.geom.Point;
class FluffBall extends Sprite {
	private var _bodyRadius:Number;
	
	public function FluffBall() {
		
	}
	
	public function get bodyRadius():Number { return _bodyRadius; }
	public function set bodyRadius(value:Number):void 
	{
		_bodyRadius = value;
	}
}

class FluffBallDirector {
	private var _bodyRadius:Number =  60;
	private var _bodyColor:uint = 0x000000;
	//毛先
	private var _topcoatColorUpside:uint = 0x77cc44;
	private var _topcoatColorDownside:uint = 0x339900;

	//根本
	private var _underlayerColorUpside:uint = 0x337711;
	private var _underlayerColorDownside:uint = 0x000000;

	private var _force:Point = new Point(0,1);	
	private var _quality:Number = 30;
	
	public function build(builder:FluffBallBuilder):FluffBall {
		builder.initialize();
		builder.quality = _quality;
		builder.drawBody(_bodyRadius, _bodyColor);
		builder.drawCoat(_underlayerColorUpside, _underlayerColorDownside, _topcoatColorUpside, _topcoatColorDownside);
		return builder.getInstance();
	}
	public function get bodyRadius():Number { return _bodyRadius; }
	public function set bodyRadius(value:Number):void 
	{
		if (value < 0) {
			value = 0;
		}
		_bodyRadius = value;
	}
	
	public function get quality():Number { return _quality; }
	public function set quality(value:Number):void 
	{
		_quality = value;
	}
}
class FluffBallBuilder {
	private var _ball:FluffBall;
	private var _quality:int;
	private var _impulse:Number = 10;
	private var _hairLength:Number = 5;
	private var _fx:Number = 0;
	private var _fy:Number = 1;
	public function FluffBallBuilder() {
		
	}
	public function initialize():void {
		_ball = new FluffBall();
		_ball.cacheAsBitmap = true;
	}
	
	public function drawBody(radius:Number, color:uint):void {
		var g:Graphics = _ball.graphics;
		g.beginFill(color);
		g.drawCircle(0, 0, radius);
		g.endFill();
		_ball.bodyRadius = radius;
	}
	
	public function drawCoat(underlayerColorUpside:uint, underlayerColorDownside:uint, topcoatUpside:uint, topcoatDownside:uint):void {
		var cos:Function = Math.cos;
		var sin:Function = Math.sin;
		var _2PI:Number = Math.PI * 2;
		
		var brad:Number = _ball.bodyRadius;
		var inv_brad:Number = 1 / brad;

		var d_th:Number = 0.5 * Math.PI / _quality; 
		for (var tmp_th:Number = 0; tmp_th < Math.PI * 0.5; tmp_th += d_th ) {
			var rad:Number = brad * cos(tmp_th);
			var z:Number = brad * sin(tmp_th);
			//var z:Number = brad * cos(tmp_th);
			//var rad:Number = brad * sin(tmp_th);
			
			var q:Number = _quality * (rad / brad);
			var d_th2:Number = 2 * Math.PI / q;
			for (var tmp_th2:Number = 0; tmp_th2 < 2 * Math.PI; tmp_th2 += d_th2 ) {
				//trace("th2", tmp_th2);
				var c:Number = cos(tmp_th2);
				var s:Number = sin(tmp_th2);
				var x:Number = rad * c + 4 * (Math.random() - 0.5);
				var y:Number = rad * s + 4 * (Math.random() - 0.5);
				var vx:Number = _impulse * c * (Math.random() + 0.5) * 0.4;
				var vy:Number = _impulse * s * (Math.random() + 0.5) * 0.4;
				
				var vrate:Number = (brad + y) / (brad + brad);// + Math.random() * 0.4;
				var underlayer:uint = ColorUtil.mixColorRGB(underlayerColorUpside, underlayerColorDownside, vrate);
				var topcoat:uint = ColorUtil.mixColorRGB(topcoatUpside, topcoatDownside, vrate);
				
				drawHair(x, y, vx, vy, underlayer, topcoat);
			}
		}
	}
	private function drawHair(x:Number, y:Number, vx:Number, vy:Number, c1:uint, c2:uint):void {
		var posx:Number, posy:Number;
		var rate:Number;
		for (var i:Number = 0; i <= _hairLength; i+=1) {
			posx = x;
			posy = y;
			vx += _fx;
			vy += _fy;
			x += vx;
			y += vy;
			rate  = (i / _hairLength);
			drawLine(posx, posy, x, y, ColorUtil.mixColorRGB(c1, c2, rate), 1 - rate);
		}
	}
	private function drawLine(from_x:Number, from_y:Number, to_x:Number, to_y:Number, c1:uint, a:Number):void {
		var g:Graphics = _ball.graphics;
		g.lineStyle(2, c1, a);
		g.moveTo(from_x, from_y);
		g.lineTo(to_x, to_y);
	}
	public function getInstance():FluffBall {
		return _ball;
	}
	
	public function get quality():int { return _quality; }
	public function set quality(value:int):void 
	{
		_quality = value;
	}
}

class ColorUtil {
	public static function decodeRGB(rgb:uint):Vector.<uint> {
		var v:Vector.<uint> = new Vector.<uint>(3, true);
		v[0] = (rgb >> 16) 	& 0x000000ff;
		v[1] = (rgb >> 8) 	& 0x000000ff;
		v[2] =  rgb 		& 0x000000ff;
		return v;
	}
	public static function encodeRGB(c:Vector.<uint>):uint {
		var color:uint;
		color = (c[0] << 16) | (c[1] << 8) | (c[2]);
		return color;
	}
	public static function mixColorRGB(colorA:uint, colorB:uint, mixRate:Number):uint {
		var mixed:uint;
		var ca:Vector.<uint>;
		var cb:Vector.<uint>;
		var r1:Number, r2:Number;
		if (mixRate <= 0) {
			mixed = colorA;
		} else if (mixRate >= 1) {
			mixed = colorB;
		} else {
			r1 = mixRate;
			r2 = 1 - mixRate;
			ca = ColorUtil.decodeRGB(colorA);
			cb = ColorUtil.decodeRGB(colorB);
			ca[0] = ca[0] * r2 + cb[0] * r1;
			ca[1] = ca[1] * r2 + cb[1] * r1;
			ca[2] = ca[2] * r2 + cb[2] * r1;
			mixed = ColorUtil.encodeRGB(ca);
		}
		return mixed;
	}
}