かえで
...
@author Motoki Matsumoto
/**
* Copyright mtok ( http://wonderfl.net/user/mtok )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/djMk
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import org.libspark.thread.EnterFrameThreadExecutor;
import org.libspark.thread.Thread;
/**
* ...
* @author Motoki Matsumoto
*/
public class Kaede extends Sprite
{
public function Kaede()
{
if (!stage) {
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}else {
initialize();
}
}
private function addedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
initialize();
}
private function initialize():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
if (!Thread.isReady) {
Thread.initialize( new EnterFrameThreadExecutor() );
}
var th:MainThread = new MainThread(this);
th.start();
}
}
}
import flash.system.LoaderContext;
import flash.text.TextField;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.net.URLRequest;
import org.libspark.thread.Thread;
import org.libspark.thread.threads.display.LoaderThread;
import org.libspark.thread.utils.ParallelExecutor;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.utils.getTimer;
class MainThread extends Thread {
private var _numLeaves:int = 30;
private var _leaves:Array;
private var _sw:Number = 0;
private var _sh:Number = 0;
private var _sprite:Sprite;
private var lt1:LoaderThread;
private var lt2:LoaderThread;
private var _noise:BitmapData;
private var _g:Vector3D = new Vector3D(0, 0.1, 0);
private var _cellSize:Number = 30;
private var _t:int;
private var _grid:Grid;
private var _mPos:Point;
private var _tf:TextField;
public function MainThread(sprite:Sprite):void
{
this.sprite = sprite;
}
override protected function run():void
{
var furl:String = "http://assets.wonderfl.net/images/related_images/2/2b/2b27/2b2786cdf19f4c69bf6ab81fe1f2b144eab834f7";
var burl:String = "http://assets.wonderfl.net/images/related_images/e/e5/e541/e54190ff73f718a4fac555ddde64b0d7fcf396c0";
var context:LoaderContext = new LoaderContext(true);
lt1 = new LoaderThread(new URLRequest(furl), context);
lt2 = new LoaderThread(new URLRequest(burl), context);
var p:ParallelExecutor = new ParallelExecutor();
p.addThread(lt1);
p.addThread(lt2);
p.start();
p.join();
next(setup);
}
private function setup():void
{
_t = getTimer();
_mPos = new Point(_sprite.mouseX, _sprite.mouseY);
setBackground();
createGrid();
createLeaves();
next(loop);
}
private function setBackground():void
{
var bg:Sprite = new Sprite();
bg.graphics.beginFill(0x000000);
bg.graphics.drawRect(0, 0, _sprite.stage.stageWidth, _sprite.stage.stageHeight);
bg.graphics.endFill();
_sprite.addChild(bg);
}
private function createLeaves():void
{
var fbmp:Bitmap;
fbmp = lt1.loader.contentLoaderInfo.content as Bitmap;
var bbmp:Bitmap;
bbmp = lt2.loader.contentLoaderInfo.content as Bitmap;
_leaves = new Array(_numLeaves);
for ( var i:int = 0; i < _numLeaves; i++) {
var tf:Leaf = new Leaf();
_sprite.addChild(tf);
tf.frontSide = new Bitmap(fbmp.bitmapData);
tf.backSide = new Bitmap(bbmp.bitmapData);
tf.frontSide.x = - tf.frontSide.width * 0.5;
tf.frontSide.y = - tf.frontSide.height * 0.5;
tf.backSide.x = - tf.backSide.width * 0.5;
tf.backSide.y = - tf.backSide.height * 0.5;
var ix:int = Math.random() * _sw;
var iy:int = Math.random() * _sh;
tf.x = ix;
tf.y = iy;
var rgb:Vector.<int> = ColorUtil.decodeToRGB(_noise.getPixel(ix,iy));
tf.rotationX = 4 * 360 * rgb[0] / 256;
tf.rotationY = 4 * 360 * rgb[1] / 256;
_leaves[i] = tf;
}
}
private function createGrid():void
{
var rows:int = Math.ceil(_sprite.stage.stageWidth / _cellSize);
var cols:int = Math.ceil(_sprite.stage.stageHeight / _cellSize);
_grid = new Grid(rows, cols);
for (var i:int = 0; i < rows; i++) {
for (var j:int = 0; j < cols; j++) {
_grid.setDataAt(i, j, new Vector3D() );
}
}
}
private function loop():void
{
var t:int = getTimer();
var dt:Number = (t - _t) * 0.001;
var p:Point = new Point(_sprite.mouseX, _sprite.mouseY);
var delta:Point = p.subtract(_mPos);
var r:int = Math.floor(p.x / _cellSize);
var c:int = Math.floor(p.y / _cellSize);
for (var j:int = r - 3; j < r + 3; j++) {
for (var k:int = c - 3; k < j + 3; k++) {
var data:Vector3D = _grid.getDataAt(j, k) as Vector3D;
if (data != null) {
data.x += delta.x * 0.01;
data.y += delta.y * 0.01;
}
}
}
for (var i:int = 0; i < _numLeaves; i++) {
var l:Leaf= _leaves[i];
r = Math.floor( l.x / _cellSize);
c = Math.floor( l.y / _cellSize);
var v:Vector3D = _grid.getDataAt(r, c) as Vector3D;
if (v != null) {
l.applyForce(v.x, v.y, v.z);
}
l.applyForce(_g.x, _g.y, _g.z);
l.step(dt);
var ix:int = int(l.x);
var iy:int = int(l.y);
var rgb:Vector.<int> = ColorUtil.decodeToRGB(_noise.getPixel(ix, iy));
if ( 0 < ix && ix < _sw) {
if (0 < iy && iy < _sh) {
l.rotationX += 2 * rgb[0] / 256;
l.rotationY += 2 * rgb[1] / 256;
}
}
if (l.y > _sh + 50) {
l.y = -30;
l.x = _sw * Math.random();
l.reset();
}
l.updateDisplay();
}
for (i = 0; i < _grid.cols; i++) {
for (j = 0; j < _grid.rows; j++) {
v = _grid.getDataAt(j, i) as Vector3D;
v.scaleBy(0.8);
}
}
_t = t;
_mPos = p;
next(loop);
}
public function get sprite():Sprite { return _sprite; }
public function set sprite(value:Sprite):void
{
_sw = value.stage.stageWidth;
_sh = value.stage.stageHeight;
_sprite = value;
if (_noise != null) {
_noise.dispose();
}
_noise = new BitmapData(int(_sw), int(_sh));
_noise.perlinNoise(_sw, _sh, 2, 3, true, true);
}
}
class Grid {
private var _rows:int = 0;
private var _cols:int = 0;
private var _data:Array;
public function Grid(rows:int, cols:int):void
{
_rows = rows;
_cols = cols;
_data = new Array(rows * cols);
}
public function getDataAt(row:int, col:int):*
{
if ( 0 <= row && row < _rows) {
if ( 0 <= col && col < _cols) {
return _data[ col * _rows + row];
}
}
return null;
}
public function setDataAt(row:int, col:int, data:*):void
{
if ( 0 <= row && row < _rows) {
if ( 0 <= col && col < _cols) {
_data[col * _rows + row] = data;
}
}
}
public function get rows():int { return _rows; }
public function get cols():int { return _cols; }
}
class TwoFacedSprite extends Sprite {
private var _frontSide:DisplayObject;
private var _backSide:DisplayObject;
private var _zAxis:Vector3D = new Vector3D(0, 0, 10000);
public function TwoFacedSprite():void
{
super();
z = 0;
addChild(_frontSide = new Sprite());
addChild(_backSide = new Sprite());
_backSide.visible = false;
if (stage) {
initialize();
}else {
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
}
private function addedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
initialize();
}
private function initialize():void
{
//addEventListener(Event.RENDER, renderHandler);
//stage.invalidate();
}
private function renderHandler(e:Event):void
{
updateDisplay();
}
public function isForward():Boolean
{
var mat:Matrix3D;
if (!stage) {
mat = transform.matrix3D;
}else {
mat = transform.getRelativeMatrix3D(root);
}
var gZ:Vector3D = mat.deltaTransformVector(_zAxis);
return gZ.dotProduct(_zAxis) > 0;
}
public function updateDisplay():void {
_frontSide.visible = isForward();
_backSide.visible = !_frontSide.visible;
}
public function get frontSide():DisplayObject { return _frontSide; }
public function set frontSide(value:DisplayObject):void
{
//null check
if ( value == null) {
throw new TypeError('object is null');
}
removeChild(_frontSide);
_frontSide = value;
addChild(_frontSide);
_frontSide.visible = isForward();
}
public function get backSide():DisplayObject
{
return _backSide;
}
public function set backSide(value:DisplayObject):void
{
if (value == null) {
throw new TypeError('object is null');
}
removeChild(_backSide);
_backSide = value;
addChild(_backSide);
_backSide.visible = !isForward();
}
}
class Leaf extends TwoFacedSprite {
public var a:Vector3D = new Vector3D(0, 0, 0);
public var v:Vector3D = new Vector3D(0, 0, 0);
public var friction:Number = 0.02;
public function applyForce(fx:Number, fy:Number, fz:Number):void
{
a.x += fx;
a.y += fy;
a.z += fz;
}
public function reset():void
{
a.x = a.y = a.z = 0;
v.x = v.y = v.z = 0;
}
public function step(dt:Number):void
{
v.x += a.x;
v.y += a.y;
v.z += a.z;
x += dt * v.x;
y += dt * v.y;
z += dt * v.z;
if ( v.lengthSquared > 100) {
v.normalize();
v.scaleBy(100);
}
}
}
class ColorUtil {
static public function decodeToRGB(c:uint):Vector.<int>
{
var rgb:Vector.<int> = new Vector.<int>(3);
rgb[0] = (c & 0xff0000) >> 16;
rgb[1] = (c & 0x00ff00) >> 8;
rgb[2] = (c & 0x0000ff);
return rgb;
}
static public function decodeToARGB(c:uint):Vector.<int>
{
var argb:Vector.<int> = new Vector.<int>(4);
argb[0] = (c & 0xff000000) >> 24;
argb[1] = (c & 0x00ff0000) >> 16;
argb[2] = (c & 0x0000ff00) >> 8;
argb[3] = (c & 0x000000ff);
return argb;
}
}