forked from: forked from: Marimo
forked from forked from: Marimo (diff: 289)
... @author ...
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;
}
}