forked from: TearPaperEffect
しっぽ流デザインパターン講座(F-site講演資料)
(http://sipo.jp/blog/2010/11/f-site.html)
で使用されているエフェクト効果です。
文字や絵が何もしなくても手が込んでる感じになるので
とても便利です。
文字は入力可能。
/**
* Copyright h_sakurai ( http://wonderfl.net/user/h_sakurai )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/tb8E
*/
// forked from h_sakurai's forked from: forked from: BumpMap
// forked from Teh's forked from: BumpMap
// forked from psyark's BumpMap
package {
import flash.media.Video;
import flash.display.BitmapData;
import flash.events.Event;
import flash.display.Sprite;
import flash.filters.ColorMatrixFilter;
import flash.filters.ShaderFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
import flash.geom.Rectangle;
import flash.display.TriangleCulling;
import flash.geom.Point;
[SWF(width=465,height=465,frameRate=60,backgroundColor=0x0)]
public class BumpMap extends Sprite {
private var vertices:Vector.<Number> = new Vector.<Number>(0, false);
private var projected:Vector.<Number> = new Vector.<Number>(0, false);
private var indices:Vector.<int> = new Vector.<int>(0, false);
private var uvtData:Vector.<Number> = new Vector.<Number>(0, false);
private var projection:PerspectiveProjection = new PerspectiveProjection();
private var count:uint = 0;
private var texture:BitmapData = new BitmapData(128, 128, false, 0x040404);
public function BumpMap() {
x = y = 465 / 2;
projection.fieldOfView = 60;
// テクスチャ作成
for (var i:int = 0; i < 16; i++) {
for (var j:int = 0; j < 32; j++) {
texture.fillRect(new Rectangle(j*4,i*16+2,3,12), 0x338855);
}
}
var w:int = 4000;
var h:int = 8000;
for(i=0;i< 4; i++) {
cs.push(new Block().set(
new Point(-6000,0),new Point(-6000,6000),new Point(6000,0), new Point(000,6000)
));
cs[i].y = i*-6000;
}
addEventListener(Event.ENTER_FRAME, enterFrame);
var s:Sprite = new TearPaperEffect();
s.x = -230;
s.y = -230;
addChild(s);
}
private var cs:Array = [];
private var in2:Vector.<int> = new Vector.<int>();
private function enterFrame(event:Event):void {
var view:Matrix3D = new Matrix3D();
view.appendRotation( 0, Vector3D.Y_AXIS);
view.appendTranslation(0, 3000, 0);
view.appendRotation( 50, Vector3D.X_AXIS);
view.append(projection.toMatrix3D());
vertices.length = 0;
indices.length = 0;
uvtData.length = 0;
for each(var c:Block in cs) {
c.y-=100;
if (c.y < -6000) {
c.set(
new Point(-3000,0),new Point(-3000,6000),new Point(3000,0), new Point(3000,6000)
);
c.y += 6000*cs.length;
}
c.addPoss(vertices, indices, uvtData);
}
Utils3D.projectVectors(view, vertices, projected, uvtData);
// ここでソートするためのデータを作成する
// 必要なデータは頂点番号3つとソートするための値(uvtのTの合計
var len:int = indices.length;
var dts:Array = new Array(len/3);
var n:int = 0;
var a1:Number;
var b1:Number;
var c1:Number;
for (var i:int = 0; i < len; n++) {
dts[n] = new Dt(indices[i++],indices[i++],indices[i++]);
a1 = uvtData[dts[n].a*3+2];
b1 = uvtData[dts[n].b*3+2];
c1 = uvtData[dts[n].c*3+2];
if(a1 > 0 && b1 > 0 && c1 > 0) {
dts[n].t = a1+b1+c1
}else {
dts[n].t = -1;
}
}
dts.sortOn("t", Array.NUMERIC);
n = 0;
for(i = 0; i < len; n++) {
if(dts[n].t==-1){
in2[i++] = 0;
in2[i++] = 0;
in2[i++] = 0;
} else {
in2[i++] = dts[n].a;
in2[i++] = dts[n].b;
in2[i++] = dts[n].c;
}
}
graphics.clear();
graphics.beginBitmapFill(texture, null, false, false);
graphics.drawTriangles(projected, in2, uvtData, TriangleCulling.NEGATIVE);
count++;
}
}
}
class Dt {
public var t:Number;
public var a:int;
public var b:int;
public var c:int;
public function Dt(a:int, b:int, c:int) {
this.a = a;
this.b = b;
this.c = c;
}
}
import flash.display.*;
import flash.geom.Point;
class Block {
public var y:Number = 0;
public var c:Cell;
public function set(p1:Point,p2:Point,p3:Point,p4:Point):Block {
c = new Cell(p1, p2, p3, p4);
for(var i:int=0;i<10;i++) {
c.leaf(new Point(Math.random() * c.width, Math.random() * c.height)).divide();
}
return this;
}
public function addPoss(vertices:Vector.<Number>, indices:Vector.<int>, uvtData:Vector.<Number>, d:int=0):void {
c.addPoss(vertices, indices, uvtData, d+y);
}
}
internal class Cell {
private var tl:Point;
private var tr:Point;
private var bl:Point;
private var br:Point;
private var d0:Point;
private var d1:Point;
private var c0:Cell;
private var c1:Cell;
private var h:Number;
public function Cell(tl:Point, tr:Point, bl:Point, br:Point) {
this.tl = tl;
this.tr = tr;
this.bl = bl;
this.br = br;
var a1:Number = 0.8*Math.random()+0.8;
var a2:Number = 0.1*Math.random()+0.9*a1;
var a3:Number = 0.1*Math.random()+0.9*a1;
h = Math.random() * Math.random() * 1200 + 200;
}
public function get width():Number {
return (tr.subtract(tl).length + br.subtract(bl).length) / 2;
}
public function get height():Number {
return (bl.subtract(tl).length + br.subtract(tr).length) / 2;
}
private function get ratio():Number {
var w:Number = width;
var h:Number = height;
return w * w / (w * w + h * h);
}
/**
* 葉っぱ検索
*/
public function leaf(p:Point):Cell {
// c0子がないなら自分を返す
if (!c0) return this;
// pとd0の差分を取る
var dp:Point = p.subtract(d0);
// d0とd1の差分を取る
var dd:Point = d1.subtract(d0);
// 差分の外積とって右か左かを判定する
if (dd.x * dp.y - dd.y * dp.x >= 0) return c0.leaf(p);// 子0を再帰的に呼び出し
else return c1.leaf(p);// 子1を再帰的に呼び出し
}
/**
* 分割
*/
public function divide():void {
var i0:Number = Math.random() * 0.5 + 0.25;
var i1:Number = i0 + Math.random() * 0.3 - 0.15;
if (Math.random() < ratio) {
// vertical
d0 = interpolate(tl, tr, i0);// tl と trの間で補間
d1 = interpolate(bl, br, i1);// bl と brの間で補間
c0 = new Cell(tl, d0, bl, d1);//
c1 = new Cell(d0, tr, d1, br);
} else {
// horizontal
d0 = interpolate(br, tr, i0);
d1 = interpolate(bl, tl, i1);
c0 = new Cell(tl, tr, d1, d0);
c1 = new Cell(d1, d0, bl, br);
}
}
private static function interpolate(p0:Point, p1:Point, i:Number):Point {
var j:Number = 1 - i;
return new Point(p0.x * j + p1.x * i, p0.y * j + p1.y * i);
}
public function addPoss(vertices:Vector.<Number>, indices:Vector.<int>, uvtData:Vector.<Number>, d:Number=0):void {
if (c0) {
c0.addPoss(vertices, indices, uvtData, d);
c1.addPoss(vertices, indices, uvtData, d);
} else {
var p:int = vertices.length/3;
var i:Number = 0.8;
var j:Number = 1 - i;
var x2:Number = tl.x*i + br.x*j;
var y2:Number = tl.y*i + br.y*j + d;
var x1:Number = tr.x*i + bl.x*j;
var y1:Number = tr.y*i + tl.y*j + d;
var x3:Number = bl.x*i + br.x*j;
var y3:Number = bl.y*i + br.y*j + d;
var x4:Number = br.x*i + bl.x*j;
var y4:Number = br.y*i + bl.y*j + d;
vertices.push(
x4, -h, y4,
x3, -h, y3,
x3, 0, y3,
x4, 0, y4,
x1, -h, y1,
x2, -h, y2,
x2, 0, y2,
x1, 0, y1,
x4, -h, y4,
x4, 0, y4
);
// uvt配列
uvtData.push(
.00, 0, 0,
.25, 0, 0,
.25, 1, 0,
.00, 1, 0,
.75, 0, 0,
.50, 0, 0,
.50, 1, 0,
.75, 1, 0,
1, 0, 0,
1, 1, 0
);
// インデックス配列
indices.push(
p+0, p+2, p+1,
p+2, p+0, p+3,
// p+2, p+3, p+6,
// p+3, p+7, p+6,
p+0, p+5, p+4,
p+1, p+5, p+0,
// p+8, p+4, p+9,
// p+4, p+7, p+9,
p+4, p+5, p+7,
p+7, p+5, p+6,
p+5, p+2, p+6,
p+2, p+5, p+1
);
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
class TearPaperEffect extends Sprite{
public function TearPaperEffect(){
var display:BitmapData = new BitmapData(456, 456, true, 0x00000000);
addChild(new Bitmap(display));
var tf:TextField = new TextField();
tf.type = TextFieldType.INPUT;
tf.multiline = true;
var format:TextFormat = tf.getTextFormat();
format.size = 40;
format.align = TextFormatAlign.CENTER;
tf.defaultTextFormat = format;
tf.text = "怪盗エディタ";
tf.width = 456;
tf.height = 456;
addChild(tf);
var original:BitmapData = display.clone();
var point:Point = new Point();
var rect:Rectangle = display.rect;
var glow:GlowFilter = new GlowFilter(0xffffff, 1, 16, 16, 2, 2);
var subGlow:GlowFilter = new GlowFilter(0xffffff, 1, 2, 2, 2, 2);
var shadow:DropShadowFilter = new DropShadowFilter(5, 90, 0x000000, 0.8, 16, 16);
addEventListener(Event.ENTER_FRAME, function (event:Event):void{
original.fillRect(rect, 0x0);
original.draw(tf);
display.applyFilter(original, rect, point, glow);
display.threshold(display, rect, point, ">", 0x00000000, 0xffffffff, 0xff000000, true);
display.applyFilter(display, rect, point, subGlow);
display.applyFilter(display, rect, point, shadow);
});
}
}