Liquid Window
/**
* Copyright nondelion ( http://wonderfl.net/user/nondelion )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/t0q7
*/
package
{
import flash.display.*;
import flash.events.Event;
import flash.geom.*;
import flash.media.Camera;
import flash.media.Video;
import flash.utils.Dictionary;
import __AS3__.vec.Vector;
import net.hires.debug.Stats;
[SWF(width="465", height="465", frameRate="30", backgroundColor="#ffffff")]
public class LiquidWindow extends Sprite
{
protected static const SIZE:int = 100; //メタボールのサイズ
protected static const NUM:int = 10; //メタボールの個数
protected static const CANVAS_WIDTH:int = 465;
protected static const CANVAS_HEIGHT:int = 465;
protected static const GRID_SPAN:uint = 20;
private var PXNUM:uint = uint(CANVAS_WIDTH / GRID_SPAN);
private var PYNUM:uint = uint(CANVAS_HEIGHT / GRID_SPAN);
private var canvas:BitmapData;
private var camera:Camera;
private var video:Video;
private var now:BitmapData;
private var old:BitmapData;
private var rect:Rectangle;
private var pt:Point;
private var alphas:Array = new Array();
private var container:Sprite = new Sprite();
private var dict:Dictionary = new Dictionary();
private var score:Vector.<int>;
private var gridPoints:Array;
public function LiquidWindow()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
canvas = new BitmapData(CANVAS_WIDTH, CANVAS_HEIGHT, true, 0x0);
var bm:Bitmap = Bitmap(addChild(new Bitmap(canvas)));
bm.scaleX = -1;
bm.scaleY = 1;
bm.x = CANVAS_WIDTH;
score = new Vector.<int>( PXNUM*PYNUM, true );
camera = Camera.getCamera();
if (camera == null) {
trace("Camera is not Connected.");
return;
}
camera.setMode(CANVAS_WIDTH, CANVAS_HEIGHT, 30);
camera.setQuality(0, 100);
video = new Video(CANVAS_WIDTH, CANVAS_HEIGHT);
video.attachCamera(camera);
now = new BitmapData(CANVAS_WIDTH, CANVAS_HEIGHT);
old = new BitmapData(CANVAS_WIDTH, CANVAS_HEIGHT);
rect = new Rectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
pt = new Point(0, 0);
score.forEach(initScore);
initBalls();
//this.addChild(new Stats());
addEventListener( Event.ENTER_FRAME, update );
addEventListener( Event.ENTER_FRAME, ballMotion );
}
private function initScore(item:int, index:int, vector:Vector.<int>):void
{
item = 0;
}
private function ballMotion(evt:Event):void
{
var ball:MetaBall;
var diff:Number;
for(var i:int=0; i<NUM; i++) {
ball = dict["ball"+i];
diff = (ball.targetX - ball.x);
ball.speedX += diff*0.1;
ball.x += ( diff + ball.speedX )*0.01;
diff = (ball.targetY - ball.y);
ball.speedY += diff*0.1;
ball.y += ( diff + ball.speedY )*0.01;
}
}
private function update( evt:Event ):void
{
now.draw(video);
now.draw(old, new Matrix(), new ColorTransform(), BlendMode.DIFFERENCE);
now.threshold(now, rect, pt, ">", 0xff111111, 0xffffffff);
canvas.lock();
canvas.fillRect(rect, 0x00000000);
canvas.draw(container);
canvas.paletteMap(canvas, rect, rect.topLeft, null, null, null, alphas);
old.threshold(canvas, rect, pt, "<", 0xff000000, 0xffffffff);
canvas.draw(old);
gridPoints = new Array();
for (var y:int = 0; y < PYNUM; y++) {
for (var x:int = 0; x < PXNUM; x++) {
var p:uint = uint(x+y*PXNUM);
var x2:Number = x*GRID_SPAN;
var y2:Number = y*GRID_SPAN;
if( now.getPixel(x2,y2) == 0xffffff ) {
score[p] += 1;
var pos:GridPoint = new GridPoint();
pos.x = x2;
pos.y = y2;
pos.score = score[p];
gridPoints.push(pos);
/*if( pos.score >= 5) {
canvas.fillRect(new Rectangle(x2-1,y2-1,3,3), 0xFFEC008C);
} else {
canvas.fillRect(new Rectangle(x2-1,y2-1,3,3), 0xFF00AEEF);
}*/
} else {
if(score[p] > 0) {
score[p] -= 1;
}
}
}
}
var len:uint = gridPoints.length;
if( len > 8 ) {
gridPoints.sortOn("score", Array.NUMERIC);
for( var i:int = 0; i<NUM && i<len; i++) {
var ball:MetaBall = dict["ball"+i];
var gp:GridPoint = gridPoints.pop();
if( gp.score > 0 ) {
//canvas.fillRect(new Rectangle(gp.x-1,gp.y-1,3,3), 0xFFEC008C);
ball.targetX = gp.x;
ball.targetY = gp.y;
}
}
}
canvas.unlock();
old.draw(video);
}
private function drawGradationCircle(g:Graphics, m:Matrix):void
{
g.beginGradientFill("radial", [0x000000,0x000000], [1,0], [110,255], m);
g.drawCircle(0, 0, SIZE);
g.endFill();
}
private function initBalls():void
{
//グラデーションサイズの調整
var adjust:Number = SIZE / (1636 / 2);
//Matrix作成
var matrix:Matrix = new Matrix();
matrix.identity();
matrix.scale(adjust,adjust);
//グラデーションボール作成
for(var i:int=0; i<NUM; i++) {
var ball:MetaBall = new MetaBall();
drawGradationCircle(ball.graphics, matrix);
ball.x = CANVAS_WIDTH/2; //グラデーションボールの初期X座標
ball.y = CANVAS_HEIGHT/2; //グラデーションボールの初期Y座標
ball.targetX = CANVAS_WIDTH/2;
ball.targetY = CANVAS_HEIGHT/2;
ball.speedX = 0;
ball.speedY = 0;
container.addChild(ball);
dict["ball" + i.toString()] = ball;
}
for(var j:int=0; j<256; j++) {
if(j < 200) { alphas.push(0); }
else { alphas.push(0xff000000); }
}
}
}
}
import flash.display.Shape;
class MetaBall extends Shape
{
public var speedX:Number;
public var speedY:Number;
public var targetX:Number;
public var targetY:Number;
public function MetaBall()
{
speedX = 0;
speedY = 0;
targetX = 0;
targetY = 0;
}
}
class GridPoint
{
public var x:Number;
public var y:Number;
public var score:Number;
public function GridPoint()
{
x = 0;
y = 0;
score = 0;
}
}