スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[ActionScript 3.0] DisplacementMapFilterで立体効果 #2

2007-12-14 | 20:25

縦方向にしか変形していないので、前回の球より置き換えマップはシンプルです。
(マウスクリックで回転/停止は切り替えられます)

package {
        import flash.display.*;
        import flash.filters.*;
        import flash.events.*;
        import flash.geom.*;
        import flash.utils.*;
        
        [SWF(width='400',height='400',backgroundColor='0xffffff')]
        public class Roll extends Sprite {
                [Embed(source=" monalisa.jpg")]
                private var Monalisa:Class;
                [Embed(source=" lena.jpg")]
                private var Lena:Class;
                [Embed(source=" seven.png")]
                private var Seven:Class;

                private var filter:BitmapData;
                private var maskBitmap:BitmapData;
               
                private var WIDTH:int = 400;
                private var HEIGHT:int = 400;
                
                private var rangeHeight:int;
                private var sw:Boolean = false;
                
                private var pics:Array = [];
                
                public function Roll( ) {
                        rangeHeight = HEIGHT/2;
                        
                        // DisplacementMapFilter用のビットマップデータ作成
                        filter = createMap(WIDTH, rangeHeight);
                        maskBitmap = createMask(rangeHeight);
                        
                        var pic:Picture = new Picture(new Lena(), 8);
                        addChild(pic.bm);
                        pics.push(pic);
                        
                        var pic2:Picture = new Picture(new Seven(), 15);
                        pic2.bm.x = pic.bm.width + 10;
                        addChild(pic2.bm);
                        pics.push(pic2);
                        
                        var pic3:Picture = new Picture(new Monalisa(), 12);
                        pic3.bm.x = pic.bm.width + pic2.bm.width + 20;
                        addChild( pic3.bm);
                        pics.push(pic3);
                        
                        var maskBm:Bitmap = new Bitmap(maskBitmap);
                        maskBm.blendMode = BlendMode.NORMAL;
                        addChild(maskBm);
                        
                        init();
                        
                        stage.addEventListener( MouseEvent.CLICK, function(e:*):void{
                                if(sw)
                                for each(var pic:Picture in pics){
                                        pic.removeEventListener(Event.ENTER_FRAME, enterFrame);
                                }
                                else
                                init();
                                sw = !sw;
                        });
                        
                }
                
                private function init():void{
                        for each(var pic:Picture in pics){
                                pic.addEventListener( Event.ENTER_FRAME, enterFrame);
                        }
                }
                
                private function enterFrame(e:*):void{
                        var pic:Picture = (Picture)(e.target);
                        pic.bm.y += pic.v;
                        if(pic.bm.y >= HEIGHT)
                        pic.bm.y = 0;
                        
                        // DisplacementMapFilterを作成
                        var pd:Point = new Point(0, HEIGHT/2 - pic.bm.y - rangeHeight/2);
                        var f:DisplacementMapFilter = new DisplacementMapFilter(filter, pd,
                                                                                                         0,BitmapDataChannel.RED, 0,200,"color",0x0);
                        // フィルタを適用
                        pic.bm.filters = [f];
                }
                
                private function createMask(d:int):BitmapData{
                        var bmp:BitmapData = new BitmapData(WIDTH, HEIGHT, true, 0xffffff);
                        for(var j:int = 0; j < HEIGHT; j++){
                                for(var i:int = 0; i < WIDTH; i++){
                                        if(Math.abs(j - HEIGHT/2) >= d/2)
                                        bmp.setPixel32(i,j,0xffffffff);
                                }
                        }
                        return bmp;
                }
                
                private function createMap(w:int, h:int):BitmapData{
                        var bmp:BitmapData = new BitmapData(w, h, false, 0x0);
                        var r:Number = h/2;
                        
                        for(var j:int = 0; j < h; j++){
                                for(var i:int = 0; i < w; i++){
                                        // displacementmap上の中心からの距離
                                        var distance:Number = j - r;
                                        // distanceに対応する点の距離(弧の長さ)
                                        var v:Number = r*Math.asin(distance/r);
                                        var offsetR:int = v - distance;
                                        var colR:int = 128 + offsetR;
                                        bmp.setPixel(i, j, (colR << 16) + 128);
                                }
                        }
                        
                        return bmp;
                }
        }
}

import flash.display.*;
internal class Picture extends Sprite{
        public var v:int;
        public var bm:Bitmap;
        public function Picture(bm:Bitmap, v:int){
                this.v = v;
                this.bm = bm;
        }
}

スポンサーサイト

Comment

Post a comment

Secret

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。