Beautifl - Flash Gallery

Thumbnail : 山手線のマナー講座のアレ
山手線のマナー講座のアレ
uwi 2009-09-01 MIT License

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

package {
    import flash.display.Sprite;
    import flash.events.*;
    import flash.geom.*;
    import flash.text.*;
    import org.papervision3d.view.*;
    import org.papervision3d.scenes.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.objects.special.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.render.*;
    import org.libspark.betweenas3.*;
    import org.libspark.betweenas3.tweens.*;
    import org.libspark.betweenas3.easing.*;
    
    // 視点を変えたりして楽しんでみてください
    [SWF(frameRate="30", backgroundColor = "#eeeeee")]
    public class FlashTest extends Sprite {
        private var _vp : Viewport3D;
        private var _s : Scene3D;
        private var _c : Camera3D;
        private var _cm : ColorMaterial;
        private var _ml : MaterialsList;
        private var _cube : DisplayObject3D;
        private var _bre : BasicRenderEngine;
        // グローバルのx, y, z軸がCubeのどの軸に対応するか
        private var _state : Array = [1, 2, 3];
        // 面の対応表
        private var _faces : Array = ["front", "back", "left", "right", "top", "bottom"];
        
        // stateを回転させる
        private function rotPZ(s : Array) : Array { var d : int = -s[0]; s[0] = s[1]; s[1] = d; return s; }
        private function rotMZ(s : Array) : Array { var d : int = -s[1]; s[1] = s[0]; s[0] = d; return s; }
        private function rotPX(s : Array) : Array { var d : int = -s[1]; s[1] = s[2]; s[2] = d; return s; }
        private function rotMX(s : Array) : Array { var d : int = -s[2]; s[2] = s[1]; s[1] = d; return s; }
        private function rotPY(s : Array) : Array { var d : int = -s[2]; s[2] = s[0]; s[0] = d; return s; }
        private function rotMY(s : Array) : Array { var d : int = -s[0]; s[0] = s[2]; s[2] = d; return s; }
        
        // 面を回転させる
        private function rotMFZ(s : Array) : Array { var d : String = s[5]; s[5] = s[2]; s[2] = s[4]; s[4] = s[3]; s[3] = d; return s; }
        private function rotPFZ(s : Array) : Array { var d : String = s[5]; s[5] = s[3]; s[3] = s[4]; s[4] = s[2]; s[2] = d; return s; }
        private function rotMFX(s : Array) : Array { var d : String = s[5]; s[5] = s[0]; s[0] = s[4]; s[4] = s[1]; s[1] = d; return s; }
        private function rotPFX(s : Array) : Array { var d : String = s[5]; s[5] = s[1]; s[1] = s[4]; s[4] = s[0]; s[0] = d; return s; }
        
        private var _t : ITween;
        private var _tf : TextField;
        
        public function FlashTest() {
            _tf = new TextField();
            _tf.height = 400;
            _tf.width = 200;
            
            addChild(_tf);
                
            _vp = new Viewport3D(0, 0, true, false);
            addChild(_vp);
            _s = new Scene3D();
            _c = new Camera3D();
            _bre = new BasicRenderEngine();
            
            _ml = new MaterialsList();
            _ml.addMaterial(new ColorMaterial(randomColor()), "front");
            _ml.addMaterial(new ColorMaterial(randomColor()), "back");
            _ml.addMaterial(new ColorMaterial(randomColor()), "left");
            _ml.addMaterial(new ColorMaterial(randomColor()), "right");
            _ml.addMaterial(new ColorMaterial(randomColor()), "top");
            _ml.addMaterial(new ColorMaterial(randomColor()), "bottom");
            
            _cube = new Cube(_ml, 100, 100, 100);
//            _cube = new UCS(100);
            _cube.y = 50;
            _s.addChild(_cube);
            
            _c.z = -300;
            _c.y = 150;
            _c.lookAt(_cube);
            
            addEventListener(MouseEvent.CLICK, onClick);
            
            onComplete();
        }
        
        private var _maxlen : int = 1;
        private var _dir : int = 0;
        private var _pos : int = 0;
        private const STEP : int = 100;
        private const DIRS : Array = [[-1, 0], [0, -1], [1, 0], [0, 1]];
        
        private var _start : Array;
        private var _end : Array = [0, 0];
        
        private const ZXS : Array = [2, 0, 2, 0];
        private const ROTFS : Array = [rotMZ, rotPX, rotPZ, rotMX];
        private const ROTFFS : Array = [rotMFZ, rotPFX, rotPFZ, rotMFX];
        private const THETAS : Array = [-90, 90, 90, -90];
        private const ROTS : Array = ["localRotationX", "localRotationY", "localRotationZ"];
        
        private function onClick(e : MouseEvent) : void
        {
            _t.togglePause();
        }
        
        private function onComplete() : void
        {
            _start = _end;
            _end = [_end[0] + DIRS[_dir][0] * STEP, _end[1] + DIRS[_dir][1] * STEP];
            
            // 足跡
            var plane : Plane = new Plane(_ml.getMaterialByName(_faces[5]), 100, 100);
            plane.x = _start[0];
            plane.z = _start[1];
            plane.rotationX = 90;
            _s.addChild(plane);
            
            // 回転
            var toobj : Object = {};
            var s : int = _state[ZXS[_dir]];
            
            toobj[ROTS[Math.abs(s) - 1]] = _cube[ROTS[Math.abs(s) - 1]] + THETAS[_dir] * (s > 0 ? 1 : -1);
//            _tf.appendText("" + _state + "\t" + ROTS[Math.abs(s) - 1] + "\t" + (_cube[ROTS[Math.abs(s) - 1]] + THETAS[_dir] * (s > 0 ? 1 : -1)) + "\n");
//            _tf.appendText("" + _faces + "\n");
            _state = ROTFS[_dir](_state); // Cube系の回転
            _faces = ROTFFS[_dir](_faces); // 面の回転
            
            _pos++;
            
            if(_pos == _maxlen){
                // 方向転換
                if(_dir == 1 || _dir == 3)_maxlen++;
                _dir++;
                if(_dir == 4)_dir = 0;
                _pos = 0;
            }
            _t = BetweenAS3.to(_cube, toobj, 0.5);
            _t.onUpdate = onUpdate;
            _t.onComplete = onComplete;
            _t.play();
        }
        
        private var _crot : Number = 0.0;
        
        private function onUpdate() : void
        {
            // ころころする
            var a : Number = _t.position / _t.duration;
            var t : Number = (90 * a + 45) / 180 * 3.1416;
            _cube.y = STEP / 2 * Math.sqrt(2) * Math.sin(t);
            _cube.x = (_end[0] + _start[0]) / 2 + (_start[0] - _end[0]) / Math.sqrt(2) * Math.cos(t);
            _cube.z = (_end[1] + _start[1]) / 2 + (_start[1] - _end[1]) / Math.sqrt(2) * Math.cos(t);
            
            // 毎回カメラ動かす
            var r : Number = 300 + Math.sqrt(_crot * 500);
            _c.z = -r * Math.cos(_crot);
            _c.x = r * Math.sin(_crot);
            _c.y = r;
            _c.lookAt(_cube);
            _crot += 0.01;
            
            _bre.renderScene(_s, _c, _vp);
        }
        
        private function randomColor() : uint
        {
            return  (Math.random() * 256) << 16 | 
                    (Math.random() * 256) << 8 | 
                    (Math.random() * 256) << 0;
        }
    }
}