Beautifl - Flash Gallery

Thumbnail : PV3D 練習その3「時計」
PV3D 練習その3「時計」
toyoshim 2009-10-02 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// forked from toyoshim's PV3D 練習その2
// forked from toyoshim's PV3D 練習その1
/*
 * 時計を作ってみることに。。。
 */
package {
    import flash.display.*;
    import flash.events.*;
 
    import org.papervision3d.view.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.typography.*;
    import org.papervision3d.typography.fonts.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.materials.special.*;
    import org.papervision3d.core.effects.view.*;
    import org.papervision3d.core.render.filter.*;
    
    import net.hires.debug.Stats;
 
    [SWF(backgroundColor=0x000000)]
 
//    public class PV3DClock extends ReflectionView
    public class PV3DClock extends BasicView
    {
        private var rootNode    : DisplayObject3D;
        private var font        : Font3D;
        private var letterObj   : DisplayObject3D;
        private var letterMat   : Letter3DMaterial;

        private var hours       : Array;
        private var hoursBaseZ  : Number;
        private var hoursBaseY  : Number;
        private var hoursBaseX  : Number;
        private var hoursBaseR  : Number;
        private var hoursTheta  : Number;

        private var mins        : Array;
        private var minsBaseZ   : Number;
        private var minsBaseY   : Number;
        private var minsBaseX   : Number;
        private var minsBaseR   : Number;
        private var minsTheta   : Number;
 
        private var secs        : Array;
        private var secsBaseZ   : Number;
        private var secsBaseY   : Number;
        private var secsBaseX   : Number;
        private var secsBaseR   : Number;
        private var secsTheta   : Number;

        public function PV3DClock()
        {
            // 画面設定
            stage.frameRate = 60;
            renderer.filter = new FogFilter(new FogMaterial(0x000000), 16, 0, 4000);
 
            // rootNode生成
            rootNode = new DisplayObject3D();
            scene.addChild( rootNode );
 
            // 文字オブジェクト用マテリアル生成
            letterMat = new Letter3DMaterial(0xFFFFFF, 0.9);
            letterMat.oneSide = false;
            font = new HelveticaBold();
            
            // 時間テキスト生成
            hours = new Array(12);
            hoursBaseZ = 700.0;
            hoursBaseY = 0.0;
            hoursBaseX = -150.0;
            hoursBaseR = 800.0;
            hoursTheta = 0.0;
            var i:int;
            var figure:String;
            for (i = 0; i < 12; i++) {
                if (i < 9) figure = String.fromCharCode(0x31 + i);
                else figure = "1" + String.fromCharCode(0x27 + i);
                hours[i] = new Text3D(figure, font, letterMat);
                hours[i].z = hoursBaseZ - hoursBaseR * Math.sin(Math.PI * i / 6.0);
                hours[i].y = hoursBaseY + hoursBaseR * Math.cos(Math.PI * i / 6.0);
                hours[i].x = hoursBaseX;
                rootNode.addChild(hours[i]);
            }
            mins = new Array(60);
            minsBaseZ = 700.0;
            minsBaseY = 0.0;
            minsBaseX = 0.0;
            minsBaseR = 800.0;
            minsTheta = 0.0;
            for (i = 0; i < 60; i++) {
                if (i < 10) figure = String.fromCharCode(0x30 + i);
                else figure = String.fromCharCode(0x30 + i / 10) + 
                              String.fromCharCode(0x30 + (i % 10));
                mins[i] = new Text3D(figure, font, letterMat);
                mins[i].z = minsBaseZ - minsBaseR * Math.sin(Math.PI * i / 30.0);
                mins[i].y = minsBaseY + minsBaseR * Math.cos(Math.PI * i / 30.0);
                mins[i].x = minsBaseX;
                rootNode.addChild(mins[i]);
            }
            secs = new Array(60);
            secsBaseZ = 700.0;
            secsBaseY = 0.0;
            secsBaseX = 150.0;
            secsBaseR = 800.0;
            secsTheta = 0.0;
            for (i = 0; i < 60; i++) {
                if (i < 10) figure = String.fromCharCode(0x30 + i);
                else figure = String.fromCharCode(0x30 + i / 10) +
                              String.fromCharCode(0x30 + (i % 10));
                secs[i] = new Text3D(figure, font, letterMat);
                secs[i].z = secsBaseZ - secsBaseR * Math.sin(Math.PI * i / 30.0);
                secs[i].y = secsBaseY + secsBaseR * Math.cos(Math.PI * i / 30.0);
                secs[i].x = secsBaseX;
                rootNode.addChild(secs[i]);
            }
            var c1:Text3D = new Text3D(":", font, letterMat);
            c1.z = -100.0;
            c1.y = 10.0;
            c1.x = -75.0;
            rootNode.addChild(c1);
            var c2:Text3D = new Text3D(":", font, letterMat);
            c2.z = -100.0;
            c2.y = 10.0;
            c2.x = 75.0;
            rootNode.addChild(c2);

            // カメラ設定
            camera.z = -400;
            camera.focus = 30;
            camera.zoom = 10;

            // デバッグ情報
//            stage.addChild(new Stats()); 
            
            // イベント登録
            stage.addEventListener(Event.ENTER_FRAME, loop);
        }

        private function loop( event:Event ):void
        {
            // 回転
            var i:int;
            var d:Date = new Date();
            var newHoursTheta:Number = -Math.PI * (8 + d.hours) / 6.0;
            var newMinsTheta:Number = -Math.PI * (45 + d.minutes) / 30.0;
            var newSecsTheta:Number = -Math.PI * (45 + d.seconds) / 30.0;
            if (newHoursTheta > hoursTheta) hoursTheta += 2.0 * Math.PI;
            if (newMinsTheta > minsTheta) minsTheta += 2.0 * Math.PI;
            if (newSecsTheta > secsTheta) secsTheta += 2.0 * Math.PI;
            hoursTheta = (hoursTheta + newHoursTheta) / 2.0;
            minsTheta = (minsTheta + newMinsTheta) / 2.0;
            secsTheta = (secsTheta + newSecsTheta) / 2.0;
            for (i = 0; i < 12; i++) {
                hours[i].z = hoursBaseZ - hoursBaseR * Math.sin(hoursTheta + Math.PI * i / 6.0);
                hours[i].y = hoursBaseY + hoursBaseR * Math.cos(hoursTheta + Math.PI * i / 6.0);
            }
            for (i = 0; i < 60; i++) {
                mins[i].z = minsBaseZ - minsBaseR * Math.sin(minsTheta + Math.PI * i / 30.0);
                mins[i].y = minsBaseY + minsBaseR * Math.cos(minsTheta + Math.PI * i / 30.0);

                secs[i].z = secsBaseZ - secsBaseR * Math.sin(secsTheta + Math.PI * i / 30.0);
                secs[i].y = secsBaseY + secsBaseR * Math.cos(secsTheta + Math.PI * i / 30.0);
            }
 
            // 再レンダリング
            singleRender();
        }
    }
}