鯉のぼり
こどもの日の記念作品です
/**
* Copyright Akiyah ( http://wonderfl.net/user/Akiyah )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/l1TD
*/
// forked from codefl's with wind and gravity ff: IK Fiber
// forked from whirlpower's IK Fiber
package {
import flash.display.Sprite;
import flash.events.*;
import flash.display.*;
import flash.net.*;
import flash.system.*;
public class FlashTest extends Sprite {
private var bmd:BitmapData;
private var loader:Loader = new Loader();
Security.loadPolicyFile("http://assets.wonderfl.net/crossdomain.xml");
public function FlashTest() {
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadDone);
loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/3/3d/3d30/3d30196c1a61f9296bb7dfcc5d330ea4a2570e79"));
}
private function loadDone(e:Event):void {
bmd = new BitmapData(loader.width,loader.height,true,0x000000);
bmd.draw(loader);
// write as3 code here..
stage.addChild( new TailLine(bmd) );
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
internal class TailLine extends Bitmap
{
private var lines :Array;
private var bmd:BitmapData;
public function TailLine(bmd:BitmapData):void
{
this.bmd = bmd;
addEventListener( Event.ADDED_TO_STAGE, init );
}
private function init( e:Event ):void
{
removeEventListener( Event.ADDED_TO_STAGE, init );
bitmapData = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0x00000000 );
lines = [];
for (var i:int = 0; i < 8; i++)
{
var radius :Number = 40;
var radian :Number = -i * Math.PI*2 / 8;
var line:IKline = new IKline(60, 9);
line.x = Math.sin( radian ) * radius / 3;
line.y = Math.cos( radian ) * radius;
line.gravity = 0;
line.friction = Math.random() * 0.2 + 0.7;
line.color = 0x123456//0x334422;
lines.push( line );
}
addEventListener( Event.ENTER_FRAME, loop );
}
private var g:Number = 9.8, tg:Number = 9.8;
private var wd:Number = 0, twd:Number = 10;
private function loop( evt:Event ):void
{
var _x :Number = stage.mouseX;
var _y :Number = stage.mouseY;
bitmapData.lock();
bitmapData.fillRect( bitmapData.rect, 0x00 );
if(Math.random() < 0.1) tg = Math.random()*9.8;
if(Math.random() < 0.1) twd = Math.random()*10;
g += 0.1 * (tg - g)
wd += 0.1 * (twd - wd);
for each(var line:IKline in lines )
{
line.gravity = g;
line.wind = wd;
line.nextFrame( _x, _y );
}
bitmapData.draw( drawMouth(lines));
var i:Number = 0;
for each(line in lines )
{
var line2:IKline = lines[(i + 1) % lines.length];
bitmapData.draw( drawLine(i, line, line2));
i++;
}
bitmapData.unlock();
}
private function drawMouth(lines:Array):Shape
{
var shape :Shape = new Shape();
var g :Graphics = shape.graphics;
//g.lineStyle(3, 0x808080);
var i:Number = lines.length - 1;
var line:IKline = lines[i];
g.beginFill(0x808080);
g.moveTo( line.x + line.segments[0].x, line.y + line.segments[0].y );
for ( i = 0; i < lines.length; i++ )
{
line = lines[i];
g.lineTo( line.x + line.segments[0].x, line.y + line.segments[0].y );
}
g.endFill();
return shape;
}
private function drawLine(j:Number, line:IKline, line2:IKline):Shape
{
var segments:Array = line.segments;
var segments2:Array = line2.segments;
var leng :int = segments.length;
var shape :Shape = new Shape();
var g :Graphics = shape.graphics;
//g.lineStyle(1, 0xff0000);
for ( var i :int = 0; i < leng-1; i++ )
{
drawSquare(g, bmd, new Point(280 / 8 * i, 280 / 8 * j), 280 / 8,
new Point(line.x + segments[i].x, line.y + segments[i].y),
new Point(line.x + segments[i+1].x, line.y + segments[i+1].y),
new Point(line2.x + segments2[i].x, line2.y + segments2[i].y),
new Point(line2.x + segments2[i+1].x, line2.y + segments2[i+1].y));
}
return shape;
}
private function drawSquare(g:Graphics, bmd:BitmapData, start:Point, len:Number,
p0:Point, p1:Point, p2:Point, p3:Point):void{
var a:Triangle;
var b:Triangle;
a = new Triangle(start,
start.add(new Point(len, 0)),
start.add(new Point(0, len)));
b = new Triangle(p0, p1, p2);
drawTriangle(g, bmd, Triangle.transformMatrix(a, b), b);
a = new Triangle(start.add(new Point(len, 0)),
start.add(new Point(len, len)),
start.add(new Point(0, len)));
b = new Triangle(p1, p3, p2);
drawTriangle(g, bmd, Triangle.transformMatrix(a, b), b);
}
private function drawTriangle(g:Graphics, bmd:BitmapData,
m:Matrix, b:Triangle):void{
if(b.order()) {
g.beginBitmapFill(bmd, m);
g.moveTo(b.p0.x, b.p0.y);
g.lineTo(b.p1.x, b.p1.y);
g.lineTo(b.p2.x, b.p2.y);
g.lineTo(b.p0.x, b.p0.y);
g.endFill();
}
}
}
internal class IKline
{
public var segments /*Segment*/:Array = [];
public var x :Number = 0;
public var y :Number = 0;
public var segmentLeng :int = 20;
public var segmentNum :int = 8;
public var wind:Number = 0
public var gravity :Number = 0;
public var friction :Number = 1;
public var color :uint = 0x888888;
public function IKline(len:int, num:int):void
{
segmentLeng = len
segmentNum = num
var segment:Segment = new Segment( 0 * i );
segments.push( segment );
for (var i:int = 1; i < segmentNum; i++)
{
segment = new Segment( segmentLeng-0.5 * i );
segments.push( segment );
}
}
public function nextFrame( _x:int, _y:int ):void
{
drag( segments[0], _x, _y );
for ( var i:int = 1; i < segmentNum; i++ )
{
var segmentA:Segment = segments[i];
var segmentB:Segment = segments[i - 1];
drag( segmentA, segmentB.x, segmentB.y );
}
}
private function drag( segment:Segment, xpos:Number, ypos:Number ):void
{
segment.next();
var dx :Number = xpos - segment.x;
var dy :Number = ypos - segment.y;
var radian :Number = Math.atan2( dy, dx );
segment.rotation = radian * 180 / Math.PI;
var pin :Point = segment.getPin();
var w :Number = pin.x - segment.x;
var h :Number = pin.y - segment.y;
segment.x = xpos - w;
segment.y = ypos - h;
segment.setVector();
segment.vx *= friction;
segment.vy *= friction;
segment.vx += wind
segment.vy += gravity;
}
}
internal class Segment extends Sprite
{
private var segmentLeng :Number;
public var vx :Number = 0;
public var vy :Number = 0;
private var prevX :Number = 0;
private var prevY :Number = 0;
public function Segment( segmentLeng:Number ):void
{
this.segmentLeng = segmentLeng;
}
public function next():void
{
x += vx;
y += vy;
}
public function setVector():void
{
if( prevX ) vx = x - prevX;
if( prevY ) vy = y - prevY;
prevX = x;
prevY = y;
}
public function getPin():Point
{
var angle :Number = rotation * Math.PI / 180;
var xpos :Number = x + Math.cos( angle ) * segmentLeng;
var ypos :Number = y + Math.sin( angle ) * segmentLeng;
return new Point( xpos, ypos );
}
}
class Triangle {
public var p0:Point;
public var p1:Point;
public var p2:Point;
function Triangle(p0:Point, p1:Point, p2:Point) {
this.p0 = p0;
this.p1 = p1;
this.p2 = p2;
}
public function matrix():Matrix {
return new Matrix(
p1.x - p0.x, p1.y - p0.y,
p2.x - p0.x, p2.y - p0.y);
}
public function order():Boolean {
return (p2.x - p0.x) * (p2.y - p1.y) - (p2.y - p0.y) * (p2.x - p1.x) >= 0 ;
}
public static function transformMatrix(a:Triangle, b:Triangle):Matrix {
var ma : Matrix = a.matrix();
ma.invert();
var mb : Matrix = b.matrix();
var m : Matrix = new Matrix();
m.translate(-a.p0.x, -a.p0.y);
m.concat(ma);
m.concat(mb);
m.translate(b.p0.x, b.p0.y);
return m;
}
}