Beautifl - Flash Gallery

Thumbnail : 綺麗なキューブ
綺麗なキューブ
kuma360 2010-08-08 MIT License

Flash Player is required to play. Please revisit at the desktop browser.

//http://www.youtube.com/watch?v=5wiwi74ek1A&feature=watch_response
//Onwards by Traction というメガデモに影響されて作った紫キューブ。再現できねぇ。
//
package 
{
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    
    [SWF ( width = 465, height = 465, frameRate = 60 )];
    public class Main extends Sprite 
    {
        private var _EFFECT1:BitmapData ;
        private var _EFFECT2:BitmapData ;
        private var _SCREEN:BitmapData ;
        private var _CANVAS:BitmapData ;
        private var _cube1:Cube ;
        private var _cube2:Cube ;
        
        public static var _L:Vector3D ;
        public static var _RX:Vector3D ;
        public static var _RY:Vector3D ;
        public static var _RZ:Vector3D ;
        
        
        
        public function Main():void {
            
            _EFFECT1 = new BitmapData ( stage.stageWidth , stage.stageHeight , true , 0 ) ;
            _EFFECT2 = new BitmapData ( stage.stageWidth , stage.stageHeight , true , 0 ) ;
            _SCREEN = new BitmapData ( stage.stageWidth , stage.stageHeight , true , 0 ) ;
            _CANVAS = new BitmapData ( stage.stageWidth , stage.stageHeight , false , 0 ) ;
            addChild ( new Bitmap ( _CANVAS ) ) ;

            _L = new Vector3D ( .1 , 1 , 0 ) ;
            _L.normalize () ;
            
            _RX = new Vector3D ( 1, 0, 0 ) ;
            _RY = new Vector3D ( 0, 1, 0 ) ;
            _RZ = new Vector3D ( 0, 0, 1 ) ;
            
            _cube1 = new Cube (   0 ) ;
            _cube2 = new Cube ( 100 ) ;
            addEventListener ( Event.ENTER_FRAME , RUN ) ;

        }

        public function RUN ( e:Event ):void {
            
            var I:int = 0 ;
            
            _SCREEN.fillRect ( _SCREEN.rect , 0 ) ;
            for ( I = 0 ; I < 20 ; ++ I ) {
                _cube1.RUN ( _SCREEN ,  I * 25 + 10 , .2 , 0 ) ;
            }
            
            for ( I = 0 ; I < 20 ; ++ I ) {
                _cube2.RUN ( _SCREEN ,  I * 25 + 10 , .3 , 1 ) ;
            }
            
            //グレアフィルター作成
            _EFFECT1.draw ( _SCREEN ) ;
            _EFFECT2.threshold ( _EFFECT1 , _EFFECT1.rect , new Point , "<" , 0xA0 , 0 , 0xFF , true ) ;
            _EFFECT1.applyFilter ( _EFFECT2 , _EFFECT2.rect , new Point , new BlurFilter ( 40 , 40 , 2 ) ) ;
            
            //描画
            _CANVAS.lock () ;
            _CANVAS.fillRect ( _CANVAS.rect , 0 ) ;
            _CANVAS.draw ( _SCREEN ) ;
            _CANVAS.draw ( _EFFECT2 , null , null, "screen" ) ;
            _CANVAS.draw ( _EFFECT1 , null , null, "screen" ) ;
            _CANVAS.unlock() ;

        }

    }
    
}

import flash.display.*;
import flash.events.*;
import flash.geom.*;

class Cube extends Sprite 
{
    private var _V:Vector.<Vector3D> ;
    private var _C:Vector.<Vector3D> ;
    private var _S:Sprite ;
    
    private var _z:Array = new Array ;
    private var _M1:Matrix3D = new Matrix3D ;
    private var _M2:Matrix = new Matrix ;
    private var _time:Number = 0 ;
    
    //////////////////////////////
    public function Cube( time:Number )  {
        
        _time = time ;
        
        const S:int = 12 ;
        
        const A:Array = [
            new Vector3D ( -S , -S , -S ) ,
            new Vector3D (  S , -S , -S ) ,
            new Vector3D (  S ,  S , -S ) ,
            new Vector3D ( -S ,  S , -S ) ,
            new Vector3D ( -S , -S ,  S ) ,
            new Vector3D (  S , -S ,  S ) ,
            new Vector3D (  S ,  S ,  S ) ,
            new Vector3D ( -S ,  S ,  S )
        ];
        
        _V = new Vector.<Vector3D>;
        _C = new Vector.<Vector3D>;
        _S = new Sprite ;
        
        for ( var I:int = 0 ; I < A.length ; ++ I ) {
            _V.push ( A[I] ) ;
            _C.push ( new Vector3D ) ;
        }
        
        
        _z = new Array ;
        
    }
    
    
    //////////////////////////////
    public function RUN ( SCREEN:BitmapData , X:int , cnt:Number , color:uint ):void {
        
        const TX:int = X ;
        const TY:int = 230 + Math.cos ( ( X + _time ) * Math.PI / 180 ) * 90 ;
        _time += cnt ;
        
        const A:Array = [
            [ 0, 1, 2, 3 ],
            [ 7, 6, 5, 4 ],
            [ 0, 4, 5, 1 ],
            [ 1, 5, 6, 2 ],
            [ 2, 6, 7, 3 ],
            [ 3, 7, 4, 0 ]
        ];
        
        var I:int ;
        
        //更新
        _M1.identity() ;
        _M1.prependRotation ( _time *  5 * Math.PI / 180 , Main._RX );
        _M1.prependRotation ( _time * 10 * Math.PI / 180 , Main._RY );
        _M1.prependRotation ( _time * 90 * Math.PI / 180 , Main._RZ );
        
        for ( I = 0 ; I < _V.length ; ++ I ) {
            _C[I] = _M1.transformVector ( _V[I] ) ;
        }
        
        // 面の中心のZ座標を求める
        for( I = 0 ; I < A.length ; ++I ){
            _z[I] = { I:I ,  Z:( _C[A[I][0]].z + _C[A[I][1]].z + _C[A[I][2]].z + _C[A[I][3]].z ) / 4 } ;
        }
    
        //Zソート
        _z.sort ( function ( a:Object , b:Object ):Number { return b.Z - a.Z; } );
        
        //描画
        var G:Graphics = _S.graphics ;
        G.clear() ;
        for ( I = 0 ; I < A.length ; ++ I ) {
            
            var J:int = _z[I].I ;
            
            //法線を求める
            var V1:Vector3D = _C[A[J][1]].subtract ( _C[A[J][0]] ) ;
            var V2:Vector3D = _C[A[J][3]].subtract ( _C[A[J][0]] ) ;
            V1 = V1.crossProduct ( V2 ) ;
            V1.normalize ( ) ;
            
            //色決定
            var D:Number = V1.dotProduct ( Main._L ) ;
            var C:int = D * 0x40 + 0x80 ;
            var COLOR:uint ;
            if ( color == 0 ) {
                if ( 0 < D ) {
                    COLOR = ( C << 16 ) | ( ( D * 0xA0 ) << 8 ) | C ;
                } else {
                    COLOR = ( C << 16 ) | C ;
                }
            } else {
                if ( 0 < D ) {
                    COLOR = ( ( D * 0xA0 ) << 16 ) | ( C << 8 ) | C ;
                } else {
                    COLOR = ( C << 8 ) | C ;
                }
            }
            
            var ALPHA:Number = .5 + ( ( D < 0 ) ? 0 : D ) ;
            
            //光の乗り方は適当
            _M2.createGradientBox ( 
                330 , 
                330 , 
                0 , 
                TX - 100 , 
                100  
            ) ;
        
            //面を描画
            G.beginGradientFill ( "radial" , [ 0xFFFFFF , COLOR ] , [ ALPHA , ALPHA ] , [ 0 , 255 ] , _M2 ) ;
            G.moveTo    ( _C[A[J][0]].x + TX , _C[A[J][0]].y + TY ) ;
            G.lineTo    ( _C[A[J][1]].x + TX , _C[A[J][1]].y + TY ) ;
            G.lineTo    ( _C[A[J][2]].x + TX , _C[A[J][2]].y + TY ) ;
            G.lineTo    ( _C[A[J][3]].x + TX , _C[A[J][3]].y + TY ) ;
            G.endFill   () ;
            
        }
        
        SCREEN.draw ( _S ) ;
            
    }
    
}