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: forked from: PaperVision3Dでハノイ

PaperVisionテスト
ブロックの表示が変なのはどうしたらよいのでしょう...
→ QuadrantRenderEngine使うと、ボリゴン欠けは多少改善されるかと思います
参考:http://clockmaker.jp/blog/2008/10/pv3d_quadtree/
Get Adobe Flash player
by gejigeji 22 Mar 2009
    Embed
// forked from clockmaker's forked from: PaperVision3Dでハノイ
// forked from masibonge's PaperVision3Dでハノイ
package{
//PaperVisionテスト
//ブロックの表示が変なのはどうしたらよいのでしょう...
// → QuadrantRenderEngine使うと、ボリゴン欠けは多少改善されるかと思います
// 参考:http://clockmaker.jp/blog/2008/10/pv3d_quadtree/
    import flash.display.*;
    import flash.events.Event;
    import flash.text.*;
    
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.render.*;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.objects.primitives.Cylinder;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.materials.special.CompositeMaterial;
    import org.papervision3d.materials.shadematerials.*;
    import org.papervision3d.lights.*;
    
    import net.hires.debug.Stats;

    public class Hanoi extends Sprite{
        private const NSTONE:int = 5;
        private const FRAME:int = 60;
        
        private var scene:Scene3D;
        private var viewport:Viewport3D;
        private var camera:ECamera3D;
        private var render:BasicRenderEngine;

        private var objStones:Array;
        private var objCylinders:Array;
        
        private var objPlane:Plane;
        
        private var light:PointLight3D;
        
        private var order:int;
        private var max_order:int;
        private var move:Array;
        private var stack:Array;
        
        //for animation
        private var count:int;
        private var speed:Number;
        private var from:int;
        private var to:int;
        private var ftop:int;
        private var ttop:int;
        private const TIME_REQ:int = 10;

        private var s:Sprite;
        private var tf:TextField;
        private var ttf:TextFormat;

        public function Hanoi(){
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.frameRate = FRAME;
            init();
            addChild(new Stats)
        }
        
        private function init():void{
            viewport = new Viewport3D(0, 0, true);
            viewport.opaqueBackground = 0;
            addChild(viewport);
            light = new PointLight3D();
            light.x = light.y = 500;
            light.z  = -100;
            
            //render
            render = new QuadrantRenderEngine(QuadrantRenderEngine.ALL_FILTERS);
            //render = new BasicRenderEngine();
            
            //camera
            camera = new ECamera3D();
            camera.y = 300;
            camera.z = -1000;
            
            camera.focus = 500;
            camera.zoom = 1;
            
            //scene
            scene = new Scene3D();
            
            //material
            var colorMat:ColorMaterial = new ColorMaterial(0x06699, 1);
            var wireMat:WireframeMaterial = new WireframeMaterial(0x0099cc);
            var compoMat:CompositeMaterial = new CompositeMaterial();
            compoMat.addMaterial(colorMat);
            compoMat.addMaterial(wireMat);
            compoMat.doubleSided = true;

            //objects
            objStones = new Array(NSTONE);
            for(var i:int=0;i<NSTONE;++i){
                objStones[i] = makeStone(compoMat, i);
                scene.addChild(objStones[i]).y = -40+55*i;
            }
            objCylinders = new Array(3);
            for(i=0;i<3;++i){
                objCylinders[i] = new Cylinder(new FlatShadeMaterial(light),10,500,10);
                objCylinders[i].y = 200;
                scene.addChild(objCylinders[i]).x = i*500-500;
            }
            
            order = 0;
            max_order = Math.pow(2, NSTONE) - 1;
            
            //array for move
            move = new Array(max_order);
            for(i=0;i<max_order;++i)
                move[i] = new Array(2);

            stack = new Array(3);
            for(i=0;i<3;++i)
                stack[i] = new Array(NSTONE);
            
            for(i=0;i<NSTONE;++i){
                stack[0][i] = i;
                stack[1][i] =  stack[2][i] = -1;
            }

            //hanoi
            recu(NSTONE, 0, 1, 2);

            //animation start
            order = count = 0;
            from = move[order][0];
            to = move[order][1];
            ftop = checkHighest(from);
            ttop = checkHighest(to);
            speed = makeSpeed(objStones[ftop].y);

            //event
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function makeStone(compoMat:CompositeMaterial, i:int):Cube{
            i = NSTONE - i;
            // グーローシェイディングはQuadrantRenderエンジンと相性がわるかったのでフラットシェーディングにしてます
            var tmp:Cube = new Cube(new MaterialsList
                                    ({all:new FlatShadeMaterial(light)}),
                                    50*i+100, 50*i+100, 50);
            tmp.x = -500;
            return tmp;
        }

        private function recu(n:int, x:int, y:int, z:int):void{
            if(n){
                recu(n - 1, x, z, y);
                move[order][0]=x;
                move[order][1]=y;
                ++order;
                recu(n - 1, z, y, x );
            }
        }

        private function checkHighest(c:int):int{
            for(var i:int=NSTONE;i--;)
                if(stack[c][i] > -1) return i;
            return -1;
        }

        private function makeSpeed(tmp:Number):Number{
            return (1000 - tmp ) / TIME_REQ ;
        }
        
        private function onEnterFrame(event:Event):void{
            if(order < max_order){
                objStones[stack[from][ftop]].y += speed;
                
                if(count == TIME_REQ){
                    objStones[stack[from][ftop]].x= 500 * to - 500;
                    objStones[stack[from][ftop]].y = 1000;
                    if(ttop<0)speed = -makeSpeed(0);
                    else  speed = -makeSpeed(objStones[stack[to][ttop]].y+80);
                }
                
                if(count > TIME_REQ * 2){
                    objStones[stack[from][ftop]].y = ttop * 55;
                    if(ttop<0)stack[to][0] = stack[from][ftop];
                    else      stack[to][ttop+1] = stack[from][ftop];
                    stack[from][ftop] = -1;

                    ++order;
                    count = 0;
                    from = move[order][0];
                    to = move[order][1];
                    ftop = checkHighest(from);
                    ttop = checkHighest(to);
                    speed = makeSpeed(objStones[ftop].y);
                }
                ++count;
            }

            camera.loop();
            
            render.renderScene(scene, camera, viewport);
        }
    }
}

import org.papervision3d.cameras.Camera3D;
class ECamera3D extends Camera3D{
    private var flag:int;
    public function ECamera3D(){
        flag = 1;
        new Camera3D();
    }
    public function loop():void{
        flag?++this.x:--this.x;
            if(this.x>1000){this.x = 999;flag=0;}
            if(this.x<-1000){this.x = -999;flag=1;}
            this.rotationY = this.rotationY - 0.09;
            flag?this.z = -Math.sqrt(1000000 - (this.x * this.x )):
                this.z = Math.sqrt(1000000 - (this.x * this.x ));
    }  
}