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

蝶と戯れるゲー

game-like sample using Papervision 3d and Tweener  
added butterfly motion using perlinNoise 
inspired by http://www.25lines.com/finalists/0812/034.txt :) 
added texture mapping for butterflies
// forked from takion's Papervision3D Game-like Sample  
//game-like sample using Papervision 3d and Tweener  

//added butterfly motion using perlinNoise 
//inspired by http://www.25lines.com/finalists/0812/034.txt :) 

//added texture mapping for butterflies

package {  
    import caurina.transitions.Tweener;
    
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Point;
    import flash.net.*;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.ui.Keyboard;
    import flash.utils.getTimer;
    import flash.system.Security; 
    import flash.system.LoaderContext;    

    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.core.clipping.FrustumClipping;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.parsers.DAE;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;  


    [SWF(backgroundColor=0x6666FF)]  
   
    public class ButterflyWatching extends Sprite  
    {  
        //private var container     : Sprite;  
        private var viewport		: Viewport3D;  
        private var scene			: Scene3D;  
        private var camera			: Camera3D;  
        private var rootNode		: DisplayObject3D;  
        private var renderer		: BasicRenderEngine;  
        private var light        	: PointLight3D;  

        //for debug  
        private var frameCount		: Number;  
        private var prevTimer		: Number;   
        private var debugText		: Array;  
        private var numDebugItems	: int = 13;  

        //camera
        private var exCamera		: Array;  
        private var cameraStatus	: int = 0; // 0: ground, 1:during change, 2:bird-eyes, 3:Look-at-paperPlane, 4:jump
       	private var maxFar			: int = 1000;
          
        //butterfly
        private var butterflies	: Array;
        private var wingMats		: Array;      
        private var bodyMat            :BitmapFileMaterial;
        private var bmpSheet		: BitmapData; 
        private var perlinPointArr	: Array;         
        private var px1			: Number = 0; 
        private var numButterflies	: int = 4;
        private var numKinds		: int = 2;
        private var butThetaRot	: Number = 0;
        private var butterflyNoise	: int = 10; 
        private var targetButterfly: int = 0;

        //ground field  
        private var fieldObj		: DisplayObject3D;  
        private var fieldSize		: int = 2000;  
        private var fieldSegment	: int = 1;  
        private var fieldMat		: ColorMaterial;  
     	private var fieldLimit		: int = fieldSize / 2 - 20;  
   
        private var rightKey		: Boolean = false;  
        private var leftKey		: Boolean = false;  
        private var upKey			: Boolean = false;  
        private var downKey		: Boolean = false;  
        private var zKey			: Boolean = false;          
        private var spaceKey		: Boolean = false;  
        private var shiftKey		: Boolean = false;
        
        private var charaHeight	: int = 50;  
        private var onJump			: Boolean = false;  
        private var deltaJump		: int = 0;  
        private var powerJump		: int = 12;  
    	private var deltaRot		: int = 2;  
     	private var deltaMove		: int = 7;  
        
        public function ButterflyWatching( ):void  
        {  

        	stage.frameRate = 30;  
            stage.quality   = "LOW";  
            stage.scaleMode = "noScale";  
            stage.align     = StageAlign.TOP_LEFT;  
   
         	viewport	= new Viewport3D( 0, 0, true );  
         	renderer	= new BasicRenderEngine( );  
            scene		= new Scene3D( );  
            rootNode	= new DisplayObject3D( );  
        	light		= new PointLight3D( );  

         	addChild( viewport );  
            scene.addChild( rootNode );  
            renderer.clipping = new FrustumClipping( FrustumClipping.BOTTOM );  
         	light.y = 2000;   
            initializeDebugger( );  
   	
            //create ground field  
         	fieldMat = new ColorMaterial( 0x888800 );  
         	fieldObj = new Plane( fieldMat, fieldSize, fieldSize, fieldSegment, fieldSegment );  
         	fieldObj.rotationX = 90;  
         	rootNode.addChild( fieldObj );      

            //create tree  
			for( var i:int = -1; i <= 1; i+=2 )
			{
				for( var j:int = -1; j <= 1; j+=2 )
				{
		            rootNode.addChild( createTree( i * 400, j * 400 ) );   
				}
			}
			rootNode.addChild( createTree( 0, 0 ) );

            //create butterfly
            butterflies = new Array( );
            perlinPointArr = new Array ( );
            wingMats = new Array( );
            Security.loadPolicyFile("http://takion.ps.land.to/images/crossdomain.xml"); 

            var wing1:BitmapMaterial = new BitmapMaterial();
            var wing2:BitmapMaterial = new BitmapMaterial();
            imageLoad( wing1, "http://takion.ps.land.to/images/wing1.png" );
            imageLoad( wing2, "http://takion.ps.land.to/images/wing2.png" );
            wingMats.push( wing1 );
            wingMats.push( wing2 );
            for( i = 0; i < numKinds; i++ )
            {
            	wingMats[ i ].oneSide = false;
            	wingMats[ i ].tiled = true;
            }
            	            
			for( i = 0; i < numButterflies; i++ )
			{           
		        rootNode.addChild( ( butterflies[ i ] = createButterfly( i % numKinds ) ) );
	    	    perlinPointArr[i] = new Point( i * 50 + 100, i * 50 + 100 );			
			}
			
			bmpSheet = new BitmapData( 40, 40, false, 0 );

            //camera setting  
            camera = new Camera3D(90, 10, maxFar, true);  
            camera.x = 300;  
            camera.y = charaHeight;  
            camera.z = 300;  
            camera.focus = 10;  
            camera.zoom = 50;  
            camera.rotationY = 300 ;  
            exCamera = new Array();  

         	//fps computing  
         	frameCount = 0;  
         	prevTimer = getTimer();  
   
            stage.addEventListener( Event.ENTER_FRAME, loop );  
            stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );  
            stage.addEventListener( KeyboardEvent.KEY_UP, keyUPHandler );  
        }  

		private function initializeDebugger():void  
		{  
			debugText = new Array();  
			var debugTextFormat:TextFormat = new TextFormat();  
			debugTextFormat.size = 11;  
			debugTextFormat.color = 0xFFFFFF;  
			debugTextFormat.font = "Courier New";  

			for( var i:int = 0; i < numDebugItems; i++ )  
			{  
				debugText[ i ] = new TextField();  
				debugText[ i ].type = "dynamic";  
				debugText[ i ].width = 150;  
				debugText[ i ].height = 20;  
				debugText[ i ].x = 12;  
				debugText[ i ].y = 8 + 15 * i;  
				debugText[ i ].defaultTextFormat = debugTextFormat;  
				//debugText[ i ].text = " --------";  
				addChild( debugText[i] );  
			}
		}

        private function imageLoad( bmpMat:BitmapMaterial, URLs:String ):void
        {
            var loaderContext:LoaderContext = new LoaderContext ();
            loaderContext.checkPolicyFile = true;

            var imageLoader:Loader = new Loader();

            imageLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, 
                function( e:Event ):void
                {
                    var loadedBmp:Bitmap = e.target.content as Bitmap;
                    var bmp : BitmapData = loadedBmp.bitmapData;
                    bmpMat.texture = bmp;
                } );
            imageLoader.load( new URLRequest( URLs ), loaderContext );
        }

        private function createTree( x:int, z:int ):DisplayObject3D
        {
            var coneMat:FlatShadeMaterial = new FlatShadeMaterial( light, 0xDDDDDD, 0x228b22 );  
            var coneObj:Cone = new Cone( coneMat, 50, 200, 8, 1 );  
            coneObj.y = 200;
            
            var trunkMat:FlatShadeMaterial = new FlatShadeMaterial( light, 0xDDDDDD, 0x8b0000 );
            trunkMat.oneSide = false;
            var trunkObj:Cylinder = new Cylinder( trunkMat, 25, 100 );
            trunkObj.y = 50;
            
            var treeObj:DisplayObject3D = new DisplayObject3D( );
            treeObj.addChild( coneObj );
            treeObj.addChild( trunkObj );
            treeObj.x = x;
            treeObj.z = z;
            return treeObj;
        }

		private function createButterfly( kind:int ):DisplayObject3D
		{
	        var butMatList: MaterialsList = new MaterialsList( );
	        butMatList.addMaterial( wingMats[ kind ], "all" );  

                 var bodyMat:BitmapMaterial = new BitmapMaterial();
                 imageLoad( bodyMat, "http://takion.ps.land.to/images/body.png" );

	        //var bodyMat:BitmapFileMaterial = new BitmapFileMaterial( ("http://takion.ps.land.to/images/body.png" ) );
	        bodyMat.tiled = true;
	        bodyMat.lineAlpha = 0.0;
	        bodyMat.lineColor = 0xFFFFFF;
	        var bodyMatList:MaterialsList = new MaterialsList();
	        bodyMatList.addMaterial( bodyMat, "all" );
	            
	        var butBody:   DAE = new DAE; 
	        var butWingRU: DAE = new DAE;
	        var butWingRD: DAE = new DAE; 
	        var butWingLU: DAE = new DAE; 
	        var butWingLD: DAE = new DAE;
	        
                 Security.loadPolicyFile("http://takion.ps.land.to/3dmodel/crossdomain.xml"); 
	        butBody.load("http://takion.ps.land.to/3dmodel/body.dae", bodyMatList); 
	        butWingRU.load("http://takion.ps.land.to/3dmodel/wingRU.dae", butMatList); 
	        butWingRD.load("http://takion.ps.land.to/3dmodel/wingRD.dae", butMatList); 
	        butWingLU.load("http://takion.ps.land.to/3dmodel/wingLU.dae", butMatList); 
	        butWingLD.load("http://takion.ps.land.to/3dmodel/wingLD.dae", butMatList); 
	            
	        butWingRU.name = "butWingRU";
	        butWingRD.name = "butWingRD";
	        butWingLU.name = "butWingLU";
	        butWingLD.name = "butWingLD";
	        butWingRU.x = butWingRD.x = 2; 
	        butWingRU.y = butWingRD.y = 0; 
	        butWingRU.z = butWingRD.z = 10; 
	        butWingLU.x = butWingLD.x = -2; 
	        butWingLU.y = butWingLD.y = 0; 
	        butWingLU.z = butWingLD.z = 10; 
					    				
	        var butterflyObj:DisplayObject3D = new DisplayObject3D();  
	        butterflyObj.addChild(butBody);  
	        butterflyObj.addChild(butWingRU);  
	        butterflyObj.addChild(butWingRD); 
	        butterflyObj.addChild(butWingLU); 
	        butterflyObj.addChild(butWingLD);  
	        butterflyObj.scale = 1; 
	        butterflyObj.y = 100;   
	        //butterflyObj.x = Math.random() * 1000 - 500; 
	        //butterflyObj.z = Math.random() * 1000 - 500; 
	        butterflyObj.rotationX = -20;
	        return butterflyObj;
		}

		private function keyDownHandler( event:KeyboardEvent ):void  
		{  
			switch ( event.keyCode )  
			{  
				case Keyboard.RIGHT:  
					rightKey = true;  
					break;  
				case Keyboard.LEFT:  
					leftKey = true;  
					break;  
				case Keyboard.UP:  
					upKey = true;  
					break;  
				case Keyboard.DOWN:  
					downKey = true;  
					break;  
				case 90: // Z key  
					zKey = true;  
					break;  
				case Keyboard.SPACE:  
					spaceKey = true;  
					break;
				case Keyboard.SHIFT:
					shiftKey = true;
					break;  
				default:      
					break;  
	        }
		}
	
		private function keyUPHandler( event:KeyboardEvent ):void  
		{
			switch ( event.keyCode )  
			{  
				case Keyboard.RIGHT:  
					rightKey = false;  
					break;  
				case Keyboard.LEFT:  
					leftKey = false;  
					break;  
				case Keyboard.UP:  
					upKey = false;  
					break;  
				case Keyboard.DOWN:  
					downKey = false;  
					break;  
				case 90:                                    
					zKey=false;  
					break;  
				case Keyboard.SPACE:  
					spaceKey = false;  
					break;
				case Keyboard.SHIFT:
					shiftKey = false;
					break; 					                      
				default:  
					break;  
			}  
		}    

		
		private function loop( event:Event ):void  
		{  
			butterflyMotion();  
			controlCamera();
			displayDebug();  
			renderer.renderScene( scene, camera, viewport );  
		}

		private function butterflyMotion():void 
		{ 
			butThetaRot += Math.PI * 2 / 100;
			butterflyNoise = Math.random() * 3 + 3; 
 			
			
			//field wandering by perlinNoise 
			
			for( var i:int = 0; i < numButterflies; i++ ) // each( var perlinPoint:Point in perlinPointArr )
			{
				var perlinPoint:Point = perlinPointArr[ i ];
				bmpSheet.perlinNoise(20,20,3,6406+i*5,true,true,2|1,false,[new Point(px1+=0.3,0),new Point(-px1/2,0),new Point(0,0)]);     
				var exPos:Point = new Point( perlinPoint.x, perlinPoint.y ); 
				var rgb24:uint=bmpSheet.getPixel( perlinPoint.x*0.025, perlinPoint.y*0.025); 
				if(rgb24>0) { 
					perlinPoint.x+=(128-(rgb24 >> 16))/5; 
					perlinPoint.y+=(128-((rgb24 ^ (rgb24 >> 16 << 16)) >> 8))/5; 
				}
				perlinPoint.x+=(800-perlinPoint.x) / int( 80 * butterflyNoise ); 
				perlinPoint.y+=(800-perlinPoint.y) / int( 80 * butterflyNoise ); 
	
				//rotate to the progressing direction 
				var vecDir:Point = new Point( perlinPoint.x - exPos.x, perlinPoint.y - exPos.y ); 
				var rotAngle:Number = Math.acos( vecDir.y / Math.sqrt( vecDir.x * vecDir.x + vecDir.y * vecDir.y ) ) * 180 / Math.PI; 
				if( vecDir.x < 0 ) rotAngle = 360 - rotAngle; //because of Z axis direction? 

				var butterflyObj:DisplayObject3D = butterflies[ i ] as DisplayObject3D;
				butterflyObj.x = (perlinPoint.x - 800); 
				butterflyObj.z = (perlinPoint.y - 800); 
				butterflyObj.rotationY = rotAngle; 
	 
				//flap wings 
				var motionPhase:Number = Math.sin( butThetaRot * 10 + i * Math.PI / 3 ) * 3;
				butterflyObj.getChildByName("butWingLU").rotationZ = motionPhase * 30; // (butterflyNoise * 3 + 5); 
				butterflyObj.getChildByName("butWingLD").rotationZ = motionPhase * 30; //(butterflyNoise * 3 + 5); 
				butterflyObj.getChildByName("butWingRU").rotationZ = - motionPhase * 30; //(butterflyNoise * 3 + 5);
				butterflyObj.getChildByName("butWingRD").rotationZ = - motionPhase * 30; //(butterflyNoise * 3 + 5);
	
				//bound motion 
				butterflyObj.y +=   Math.cos( butThetaRot * 5 ) * butterflyNoise;  
			}
		} 

		private function controlCamera():void 
		{  
			if( spaceKey == true )
			{  
				if( cameraStatus == 0 )   // on normal mode
				{  
					camera.far = 2500;
					renderer.clipping = new FrustumClipping(FrustumClipping.NEAR);  
					cameraStatus = 1;     // on changing modes
					exCamera[0] = camera.x;  
					exCamera[1] = camera.y;  
					exCamera[2] = camera.z;  
					exCamera[3] = camera.rotationX;  
					exCamera[4] = camera.rotationY;  
					exCamera[5] = camera.rotationZ;      
					Tweener.addTween( camera, {x: 0, y:2300, z:0, time:2} );  
					Tweener.addTween( camera, {rotationX: 90, time:3, onComplete: function():void{cameraStatus = 2} } );   
				}  
				else if( cameraStatus == 2 )  // on birds-eye mode
				{  
					camera.far = maxFar;
					cameraStatus = 1;  
					Tweener.addTween( camera, {x: exCamera[0], y:exCamera[1], z:exCamera[2], time:3} );  
					Tweener.addTween( camera, {rotationX: exCamera[3], time:2, onComplete: function():void  
						{  
							cameraStatus = 0;  
							renderer.clipping = new FrustumClipping(FrustumClipping.BOTTOM);  
						}} );  
					exCamera.length = 0;  
				}  
			}    

			if( zKey == true )  
			{
				if( cameraStatus == 0 )  
				{  
					exCamera[0] = camera.rotationX;  
					exCamera[1] = camera.rotationY;  
					exCamera[2] = camera.rotationZ; 
					
					var minimumDis:int = -1;
					for( var i:int = 0; i < numButterflies; i ++ )
					{
						var distance: Number = Point.distance( new Point( camera.x, camera.z ), new Point( butterflies[ i ].x, butterflies[ i ].z ) );
						if( minimumDis < 0 || distance < minimumDis )
						{
							minimumDis = distance;
							targetButterfly = i;
						}
					} 
					if(minimumDis < maxFar) cameraStatus = 3;  
				}  
			
				if( cameraStatus == 3 )  // on obserbing a butterfly mode
				{
					if( Point.distance( new Point( camera.x, camera.z ), new Point( butterflies[ targetButterfly ].x, butterflies[ targetButterfly ].z ) ) < maxFar )
					{
						camera.lookAt( butterflies[ targetButterfly ] );	
					}
					else
					{
						cameraStatus = 0;  
						camera.rotationX = exCamera[0];  
						camera.rotationY = exCamera[1];  
						camera.rotationZ = exCamera[2];  
						exCamera.length = 0; 
					}
				}  
			}  
			else  
			{  
				if( cameraStatus == 3 )  
				{  
					cameraStatus = 0;  
					camera.rotationX = exCamera[0];  
					camera.rotationY = exCamera[1];  
					camera.rotationZ = exCamera[2];  
					exCamera.length = 0;  
				}
				
				if( rightKey == true )  
				{  
					camera.rotationY += deltaRot;  
				}  
				else if( leftKey == true )  
				{      
					camera.rotationY -= deltaRot;  
				}
			}  

			if( cameraStatus == 0 )
			{
				if( camera.x > - fieldLimit && camera.x < fieldLimit && camera.z > - fieldLimit && camera.z < fieldLimit )  
				{      
					if( upKey == true )  
					{  
						camera.moveForward( deltaMove );  
					}  
					else if ( downKey == true )  
					{  
						camera.moveBackward( deltaMove );  
					}  
				}  
			}
				/*
				if( shiftKey == true )  
				{  
						cameraStatus = 4;  
						deltaJump = powerJump;  
				}
			}
				
				if( cameraStatus == 4 )  // on Jump
				{  
					camera.y += deltaJump;  
					if( deltaJump == -powerJump )  
					{  
						cameraStatus = 0;  
						deltaJump = 0;  
					}  
					else  
					{  
						deltaJump -= 1;  
					}  
				} */           

				//avoid camera going out of the field  
				if( camera.x > fieldLimit - 10 )
				{
					camera.x = fieldLimit - 10;
				}
				else if( camera.x < - fieldLimit + 10)
				{
					camera.x = - fieldLimit + 10;
				}
				else if( camera.z > fieldLimit - 10 )
				{
					camera.z = fieldLimit - 10;
				}
				else if( camera.z < - fieldLimit + 10 )
				{
					camera.z = - fieldLimit + 10;
				}
						
		}
				
		private function displayDebug():void  
		{  
			frameCount ++;  
			if ( (getTimer() - prevTimer ) / 1000 >= 0.25 )  
			{  
				var fps:Number = frameCount * 1000 / ( getTimer() - prevTimer );  
				fps = Math.floor( fps * 10 ) / 10;  
				prevTimer = getTimer();  
				frameCount = 0;  
				debugText[ 0 ].text = "FPS      : " + fps;  
			}
 			debugText[ 1 ].text = "Move     : ↑↓";  
			debugText[ 2 ].text = "Turn     : →←";  
			debugText[ 3 ].text = "Observe  : Z";  
			debugText[ 4 ].text = "Bird-eyes: Space";
			/*
			debugText[ 5 ].text = "Jump     : Shift" ;
						
			debugText[ 7 ].text = "CAMERA_X : " + int( camera.x );  
			debugText[ 8 ].text = "CAMERA_Y : " + int( camera.y );   
			debugText[ 9 ].text = "CAMERA_Z : " + int( camera.z );   
			debugText[ 10 ].text = "ROT_X    : " + int( camera.rotationX );  
			debugText[ 11 ].text = "ROT_Y    : " + int( camera.rotationY );  
			debugText[ 12 ].text = "ROT_Z    : " + int( camera.rotationZ );  
			*/
		}		
	}    
}