bloodFailling
ペンキが壁から垂れていくっぽい感じの奴
/**
* Copyright sw_lucchini ( http://wonderfl.net/user/sw_lucchini )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/cYt2
*/
// forked from glasses_factory's LiquidFailling
//ペンキが壁から垂れていくっぽい感じの奴
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width = "465",height = "465",backgroundColor="0x000000")]
public class LiquidFalling extends Sprite
{
private var main:Liquid;
private var bmd:BitmapData;
private var bmp:Bitmap;
//一度に生成出来る最大数
private const MAX_LIQUID:int = 10;
private var cnt:int;
public function LiquidFalling()
{
init();
}
//初期化
private function init():void
{
bmd = new BitmapData(465,465,true,0x00ffffff);
//一行のポイント数,描画するBitmapData
liquidGen(Math.random() * 20 + 10,bmd);
bmp = new Bitmap(bmd);
addChild(bmp);
stage.addEventListener(MouseEvent.CLICK,onClick);
}
//クリックで生成
private function onClick(e:MouseEvent):void
{
liquidGen(Math.random() * 20 + 10,bmd);
bmp.bitmapData = bmd;
}
private function liquidGen(ptNum:int,_bmd:BitmapData):void
{
//最大数より生成されていたらリターン。
if(cnt > MAX_LIQUID)
{
return;
}
else
{
main = new Liquid(ptNum,_bmd);
main.generate(-100,Math.random() * 0xFF0000);
main.addEventListener(Liquid.FAIL_OUT,failed);
cnt++;
}
}
private function failed(e:Event):void
{
cnt--;
e.target.removeEventListener(Liquid.FAIL_OUT,failed);
}
}
}
import __AS3__.vec.Vector;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
class Liquid extends Sprite
{
public static const FAIL_OUT:String = "fail_out";
private var ptNum:int;
private var bmd:BitmapData;
private var sp:Sprite;
private var ptVect:Vector.<LiquidPt>;
private var _color:uint;
private var rightEnd:LiquidPt;
private var loc1:*;
private var loc2:*;
private var loc3:*;
private var loc4:*;
private var endCnt:uint;
private var _timer:Timer;
public function Liquid(_ptNum:int,_bmd:BitmapData)
{
ptNum = _ptNum;
bmd = _bmd;
sp = new Sprite();
ptVect = new Vector.<LiquidPt>(_ptNum,true);
}
public function generate(pos:Number,col:uint):void
{
_color = col;
for(var i:int = 0; i < ptNum-1; i++)
{
loc1 = i * (465 / ptNum+1);
ptVect[i] = new LiquidPt(loc1,pos);
ptVect[i].gravity = 8;
ptVect[i].friction = 0.5;
}
ptVect[ptNum-1] = new LiquidPt(465,pos);
ptVect[ptNum-1].gravity = 8;
ptVect[ptNum-1].friction = 0.5;
//描画
draw();
//毎フレーム描画
addEventListener(Event.ENTER_FRAME,onEnter);
// 落ち始めるポイントをランダムに指定
_timer = new Timer(1000);
_timer.addEventListener(TimerEvent.TIMER,onTimer);
_timer.start();
}
public function draw():void
{
sp.graphics.clear();
sp.graphics.lineStyle(1,_color);
sp.graphics.beginFill(_color);
sp.graphics.moveTo(ptVect[0].x,ptVect[0].y);
for(var i:int = 1; i < ptNum-1; i++)
{
sp.graphics.curveTo(ptVect[i].x,ptVect[i].y,(ptVect[i].x + ptVect[i+1].x) / 2,(ptVect[i].y + ptVect[i+1].y)/2)
}
sp.graphics.curveTo(ptVect[ptNum-1].x,ptVect[ptNum-1].y,(ptVect[ptNum-1].x + 465) / 2,(ptVect[ptNum-1].y + ptVect[ptNum-1].y)/2);
sp.graphics.lineTo(465,0);
sp.graphics.lineTo(0,0);
sp.graphics.endFill();
bmd.draw(sp);
}
private function onEnter(e:Event):void
{
for(var i:int =0; i < ptNum; i++)
{
if(ptVect[i].isFalling)
{
ptVect[i].fallDown();
if(ptVect[i].y >= 465 + 465/2)
{
!ptVect[i].isFallDown ? endCnt++ : endCnt;
ptVect[i].isFallDown = true;
}
}
//ステージ中心より下に落ちたら両隣のポイントを引きずる
if(ptVect[i].y > 465/2)
{
if(i-1 >-1)
{
if(!ptVect[i-1].isFalling)
{
ptVect[i-1].isFalling = true;
//重力と抵抗をランダムにする事で何かそれっぽくなる
ptVect[i-1].gravity = Math.random() * 12 + 6;
ptVect[i-1].friction = Math.random() * 0.8 + 0.4;
}
}
if(i < ptNum-1)
{
if(!ptVect[i+1].isFalling)
{
ptVect[i+1].isFalling = true;
ptVect[i+1].gravity = Math.random() * 12 + 6;
ptVect[i+1].friction = Math.random() * 0.8 + 0.4;
}
}
}
//全てのポイントがステージより下に落ちたら落ちきった事を通知
if(endCnt >= ptNum)
{
dispatchEvent(new Event(FAIL_OUT));
removeEventListener(Event.ENTER_FRAME,onEnter);
}
}
draw();
}
private function onTimer(e:TimerEvent):void
{
//まだ落ちていないポイントを抽出
loc1 = function(item:LiquidPt,ind:int,vect:Vector.<LiquidPt>):Boolean
{
if(!item.isFalling) return true;
else return false
};
loc2 = ptVect.filter(loc1);
//落ち始めるポイントをランダムに決定
//同時に複数落とす事で液体の幅を変える
loc3 = int(Math.random() * loc2.length);
loc4 = int(Math.random() * 3);
//Vectorの中が空でなければ
if(loc2.length-1 > 0)
{
for(var i:int =0; i < loc4; i++)
{
loc2[loc3+i].isFalling = true;
}
}
//全てのポイントが落ちきったらタイマーストップ
if(loc2.length <= 0)
{
_timer.stop();
_timer.removeEventListener(TimerEvent.TIMER,onTimer);
}
}
}
import flash.geom.Point;
class LiquidPt extends Point
{
private var _vx:Number, _vy:Number;
private var _gravity:Number;
private var _friction:Number;
private var _isFalling:Boolean;
private var _moved:Boolean;
private var oldX:Number;
private var oldY:Number;
private var _isFallDown:Boolean;
public function get vx():Number
{
return _vx;
}
public function set vx(value:Number):void
{
_vx = value;
return;
}
public function get vy():Number
{
return _vy;
}
public function set vy(value:Number):void
{
_vy = value;
return;
}
public function set gravity(value:Number):void
{
_gravity = value;
return;
}
public function get gravity():Number
{
return _gravity;
}
public function get friction():Number
{
return _friction;
}
public function set friction(value:Number):void
{
_friction = value;
return;
}
public function set isFalling(value:Boolean):void
{
_isFalling = value;
return;
}
public function get isFalling():Boolean
{
return _isFalling;
}
public function set isFallDown(value:Boolean):void
{
_isFallDown = value;
return;
}
public function get isFallDown():Boolean
{
return _isFallDown;
}
public function LiquidPt(xValue:Number=0, yValue:Number=0)
{
super(xValue, yValue);
x = xValue; y = yValue;
oldX = x;
_vx = 0; _vy = 0;
}
public function fallDown():void
{
if(_isFallDown) return;
vy = gravity;
vy *= friction;
y += vy;
}
public function mouseInteraction(tPt:Point):void
{
if(Math.abs(x - tPt.x) < 40)
{
_moved = true;
vx = (tPt.x - x) * 0.5;
vx *= _friction;
x += vx;
}
else if(!_moved)
{
return
}
else
{
vx = (oldX - x) * 0.5;
vx *= _friction;
x += vx;
if(Math.abs(oldX - x) < 0.1) _moved = false;
}
if(Math.abs(y - tPt.y) < 40)
{
_moved = true;
_gravity *= 1.2;
}
else if(!_moved)
{
return;
}
}
}