/**
* Copyright Kay ( http://wonderfl.net/user/Kay )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/hb5E
*/
// 似非3D
// 膜に泡が接触すると膜に穴があきます
// 穴はLineで描かずBitmapDataに穴をあけるて表現してみました
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.filters.GlowFilter;
import flash.geom.PerspectiveProjection;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.events.Event;
public class Take01 extends Sprite {
private const SW:Number=stage.stageWidth;
private const SH:Number=stage.stageHeight;
private const GW:Number=500;
private const GH:Number=500;
private const RAD:Number=20;
private var bmd:BitmapData;
private var balls:Array = new Array();
public function Take01():void {
var bg:Shape = new Shape();
bg.graphics.beginFill(0x6fc6ff);
bg.graphics.drawRect(0,0,SW,SH);
bg.graphics.endFill();
addChild(bg);
//----------------------------------------
// 視野設定
var proj:PerspectiveProjection=root.transform.perspectiveProjection;
proj.projectionCenter=new Point(SW/2,-30);
proj.fieldOfView=35;
//----------------------------------------
// 描画用カンバスをステージ中央におく
var canvas:Sprite = new Sprite();
canvas.x=SW/2;
canvas.y=SH/2;
addChild(canvas);
canvas.addEventListener(Event.ENTER_FRAME, xDraw);
//----------------------------------------
// 球が立体に見えるように誤魔化す
var aColor:Array=new Array(0xffffff,0xffffff);
var aAlpha:Array=new Array(1,0);
var aRatio:Array=new Array(0x33,0xff);
var gMatrix:Matrix = new Matrix();
gMatrix.createGradientBox(RAD*2, RAD*2, 0, -RAD/5, -RAD/3);
var ballShape:Shape = new Shape();
ballShape.graphics.beginGradientFill(GradientType.RADIAL, aColor, aAlpha, aRatio,gMatrix,"pad","linerRGB");
ballShape.graphics.drawRect(0,0,RAD*2,RAD*2);
ballShape.graphics.endFill();
var ballBmd:BitmapData=new BitmapData(RAD*2,RAD*2,true,0x66ffffff);
var dMatrix:Matrix = new Matrix();
ballBmd.draw(ballShape);
var glow:GlowFilter = new GlowFilter();
glow.inner=true;
glow.color=0xffffff;
glow.blurX=4;
glow.blurY=4;
//----------------------------------------
// 球の位置を設定して配列に格納(奥から)
var numBalls:int=10;
var step:Number = (GH-RAD)/(numBalls+1);
for (var i:int = 0; i < numBalls; i++) {
var ball:Ball=new Ball(RAD,Math.random()*Math.PI*2,ballBmd);
ball.x = Math.random()*(GW-RAD*2)+RAD-GW/2;
ball.z = GH/2-(RAD+step*(i+1));// GH/2~-GH/2
ball.nZ=ball.z;// zの逆値
ball.filters=[glow];
balls.push(ball);
}
}
private function xDraw(e:Event):void {
//----------------------------------------
// 初期化
while (e.target.numChildren) {
e.target.removeChildAt(0);
}
var objects:Array = new Array();
var rings:Array = new Array();
var holes:Vector.<Number> = new Vector.<Number>();
//----------------------------------------
// 球の位置制御
for each (var ball:Ball in balls) {
ball.y=GH/2*Math.sin(ball.radian);
objects.push(ball);
var pos:Number=Math.abs(ball.y);
if (pos<RAD) {
var radius:Number=Math.sqrt(Math.pow(RAD,2)-Math.pow(pos,2));
holes.push(ball.x, ball.z, radius);
var ring:Ring=new Ring(ball.x,ball.z,radius);
rings.push(ring);
} else {
holes.push(ball.x, ball.z, 0);
}
ball.radian+=0.025;// 球の移動スピード
}
//----------------------------------------
// 球が貫通するプレートを3D表示
var Ground:Ground=new Ground(GW,GH,holes);
for each (var panel:Panel in Ground.plates) {
panel.rotationX=-90;
objects.push(panel);
}
//----------------------------------------
// 奥にあるものから表示
objects.sortOn("nZ", Array.NUMERIC | Array.DESCENDING);
for each (var object:Object in objects) {
e.target.addChild(object);
}
for each (var objectR:Ring in rings) {
e.target.addChild(objectR);
}
}
}
}
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.events.Event;
/*
* GroundはPlateの集合体
* 直接描画せずgetPlatesで配列として返す
*/
class Ground extends Sprite {
public var w:Number;
public var h:Number;
public var plates:Array;
public var bmd:BitmapData;
public var holes:Vector.<Number>;
public function Ground(_w:Number, _h:Number, _v:Vector.<Number>):void {
w=_w;
h=_h;
holes=_v;
plates=getPlates();
}
public function getPlates():Array {
var numHoles:int=holes.length/3;
// 穴のあいたBitmap
bmd=new BitmapData(w,h,true,0x00000000);
var ground:Sprite = new Sprite();
ground.graphics.beginFill(0x93d3ff);
ground.graphics.drawRect(0,0,w,h);
for (var i:int = 0; i < numHoles; i++) {
ground.graphics.drawCircle(w/2+holes[i*3+0],h/2-holes[i*3+1],holes[i*3+2]);
}
bmd.draw(ground);
// 穴の位置で分割された面を返す
var plates:Array = new Array();
var from:Number=h/2;// current Position
for (i = 0; i < numHoles; i++) {
var to:Number=holes[i*3+1];
var panel:Panel=new Panel(w,h,from,to,bmd);
plates.push(panel);
from=to;
}
var lastPanel:Panel=new Panel(w,h,from,- h/2,bmd);
plates.push(lastPanel);
return plates;
}
}
class Panel extends Sprite {
public var nZ:Number;
public function Panel(w:Number,h:Number,from:Number,to:Number,bmd:BitmapData):void {
var nX:Number=- w/2;
var nY:Number=- from;
var nH:Number=from-to;
var matrix:Matrix = new Matrix();
matrix.tx=- w/2;
matrix.ty=- h/2;
graphics.beginBitmapFill(bmd,matrix);
graphics.drawRect(nX, nY-1, w, nH+2);// インチキ補正
graphics.endFill();
nZ=from-nH/2;
}
}
class Ball extends Sprite {
public var radian:Number;
public var nZ:Number;
public function Ball(_radius:Number,_r:Number,bmd:BitmapData):void {
radian=_r;
var matrix:Matrix = new Matrix();
matrix.translate(-_radius,-_radius);
graphics.beginBitmapFill(bmd,matrix);
graphics.drawCircle(0,0,_radius);
graphics.endFill();
}
}
class Ring extends Sprite {
public var nZ:Number;
public function Ring(nx:Number, ny:Number, nr:Number):void {
graphics.lineStyle(2,0xffffff,0.5);
graphics.drawCircle(nx, -ny, nr+5);
graphics.lineStyle(2,0xffffff,0.25);
graphics.drawCircle(nx, -ny, nr+10);
//graphics.drawCircle(nx, -ny, nr+20);
rotationX=-90;
nZ=- ny;
}
}