In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: TearPaperEffect

しっぽ流デザインパターン講座(F-site講演資料)
(http://sipo.jp/blog/2010/11/f-site.html)
で使用されているエフェクト効果です。
文字や絵が何もしなくても手が込んでる感じになるので
とても便利です。
文字は入力可能。
Get Adobe Flash player
by h_sakurai 05 Dec 2010
/**
 * 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);
            });
            
        }
    }