forked from: 親オブジェクト自体の回転

by challengeyh forked from 親オブジェクト自体の回転 (diff: 388)
♥0 | Line 274 | Modified 2010-05-18 18:37:20 | MIT License
play

ActionScript3 source code

/**
 * Copyright challengeyh ( http://wonderfl.net/user/challengeyh )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vOMb
 */

package
{
	import caurina.transitions.Tweener;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.filters.GlowFilter;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.system.Security;

	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.view.layer.ViewportLayer;

	[SWF(backgroundColor=0x000000)]

	public class Papervision3D_sample58_2 extends Sprite
	{
		// 変数
		private var container:Sprite;
		private var viewport:Viewport3D;
		private var scene:Scene3D;
		private var camera:Camera3D;
		private var render:BasicRenderEngine;
		private var rootNode:DisplayObject3D;

		// ローディング用swf
		//[Embed(source='loading1.swf')]
		private var loading1:Class;
		private var loadSp1:Sprite;

		// ローディング用画像
		//[Embed(source='loading2.png')]
		private var loading2:Class;
		private var loadSp2:Sprite;
		private var loadingAlpha:Number=0;

		// バーの画像
		//[Embed(source='title.jpg')]
		private var title:Class;
		private var titleSp:Sprite;

		// 画像を保持する配列
		private var imgArray:Array;

		// FlickerAPI用変数
		private var apiKey:String="25c5f4bc0087edf4d6efdc567daf0a64";
		private var count:int=0;
		private var move:Boolean=false;
		private var str:String="cat";

		// コンストラクタ
		public function Papervision3D_sample58_2()
		{
			// コンテナの初期化
			container=new Sprite();
			addChild(container);
			container.x=stage.stageWidth / 2;
			container.y=stage.stageHeight / 2;

			// PV3Dの初期化
			viewport=new Viewport3D(0, 0, true, true);
			scene=new Scene3D();
			camera=new Camera3D();
			render=new BasicRenderEngine();
			rootNode=scene.addChild(new DisplayObject3D("rootNode"));
			addEventListener(Event.ENTER_FRAME, onFrame);

			// 基本設定
			addChild(viewport);
			camera.z=-900;
			camera.zoom=20;
			camera.focus=20;
			camera.target=DisplayObject3D.ZERO;

			// ステージ設定
			stage.frameRate=30;
			stage.quality=StageQuality.MEDIUM;
			stage.align=StageAlign.TOP_LEFT;
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.addEventListener(Event.RESIZE, onResize);

			// ローディングswfの設置
			loadSp1=new loading1();
			loadSp1.alpha=0;
			container.addChild(loadSp1);
			loadSp1.x=-loadSp1.width / 2;
			loadSp1.y=-loadSp1.height / 2;
			Tweener.addTween(loadSp1, {alpha: 1, time: 2});

			// ローディング用画像の作成
			loadSp2=new Sprite();
			loadSp2.addChild(new loading2() as Bitmap);
			loadSp2.alpha=0;
			container.addChild(loadSp2);
			loadSp2.x=-loadSp2.width / 2;
			loadSp2.y=-loadSp2.height / 2 + 40;
			loadSp2.addEventListener(Event.ENTER_FRAME, onloading);

			// ポリシーファイルの読み込み
			Security.loadPolicyFile("http://api.flickr.com/crossdomain.xml");
			Security.loadPolicyFile("http://farm1.static.flickr.com/crossdomain.xml");
			Security.loadPolicyFile("http://farm2.static.flickr.com/crossdomain.xml");
			Security.loadPolicyFile("http://farm3.static.flickr.com/crossdomain.xml");
			Security.loadPolicyFile("http://farm4.static.flickr.com/crossdomain.xml");

			// FlickerAPIの利用
			move=false;
			imgArray=new Array();
			var loader:URLLoader=new URLLoader();
			loader.addEventListener(Event.COMPLETE, onCompleteSearch);
			loader.load(new URLRequest("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + apiKey + "&tags=" + str + "&per_page=100"));

			// バー用画像を作成
			titleSp=new Sprite();
			titleSp.addChild((new title()) as Bitmap);
			container.addChild(titleSp);
			setBar();
		}

		// 検索結果解析関数
		private function onCompleteSearch(e:Event):void
		{
			var xml:XML=XML(e.target.data);

			if (xml.@stat == "ok")
			{
				for each (var photo:XML in xml.photos.photo)
				{
					var url:String="http://farm" + photo.@farm + ".static.flickr.com/" + photo.@server + "/" + photo.@id + "_" + photo.@secret + ".jpg";
					var req:URLRequest=new URLRequest(url);
					var loader:Loader=new Loader();
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompletePhoto);
					loader.load(req, new LoaderContext(true));
				}
			}
		}

		// plane作成
		private function onCompletePhoto(e:Event):void
		{
			var loader:Loader=(e.target as LoaderInfo).loader;
			imgArray[count]=(loader.content as Bitmap).bitmapData;
			count++;

			// 指定した枚数をロードしたら、planeを設置する
			if (count >= 100)
			{
				var c:int=0;
				for (var i:int=0; i < 20; i++)
				{
					for (var j:int=0; j < 5; j++)
					{
						var bmpd:BitmapData=imgArray[c] as BitmapData
						var mat:BitmapMaterial=new BitmapMaterial(bmpd, true);
						mat.doubleSided=mat.interactive=true;
						var p:Plane=new Plane(mat, bmpd.width / 5, bmpd.height / 5, 1, 1);
						p.extra={theta1: 0, theta2: 0, radius: 0, x: 0, y: 0, z: 0, roll: 0};
						p.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onClick);
						rootNode.addChild(p, "plane" + i.toString() + j.toString());

						var theta1:Number=Math.random() * 180 - 90;
						var r:Number=(600 - 10 * i) * Math.cos(theta1 * Math.PI / 180);
						var theta2:Number=Math.random() * 360;

						p.extra.x=r * Math.sin(theta2 * Math.PI / 180);
						p.extra.y=(600 - 10 * i) * Math.sin(theta1 * Math.PI / 180);
						p.extra.z=r * Math.cos(theta2 * Math.PI / 180);
						p.extra.theta1=theta1;
						p.extra.theta2=theta2;
						p.extra.radius=(600 - 10 * i);

						p.rotationX=-theta1;
						p.rotationY=theta2;
						p.rotationZ=0;

						c++;

						p.x=p.extra.x * 1000;
						p.y=p.extra.y * 1000;
						p.z=p.extra.z * 1000;

						if (c != 100)
						{
							Tweener.addTween(p, {x: p.extra.x, y: p.extra.y, z: p.extra.z, time: 3});
						}

						else
						{
							Tweener.addTween(loadSp1, {alpha: 0, time: 2});
							Tweener.addTween(loadSp2, {alpha: 0, time: 2});
							loadSp2.removeEventListener(Event.ENTER_FRAME, onloading);
							Tweener.addTween(p, {x: p.extra.x, y: p.extra.y, z: p.extra.z, time: 3, onComplete: function():void
								{
									move=true;
								}});
						}
					}
				}
			}
		}

		// マウスイベント用関数
		private function onClick(e:InteractiveScene3DEvent):void
		{
			var tp:Plane=e.target as Plane;
			var str:String=tp.name;
			var vpl:ViewportLayer=tp.createViewportLayer(viewport, true);

			if (tp.extra.roll == 0)
			{
				vpl.filters=[new GlowFilter(0xffffff, 0.5, 20, 20, 5)];
				move=false;
				tp.extra.roll=1;

				for (var i:int=0; i < 20; i++)
				{
					for (var j:int=0; j < 5; j++)
					{
						var p:Plane=rootNode.getChildByName("plane" + i.toString() + j.toString()) as Plane;

						if (p.name == str)
							Tweener.addTween(p, {scale: 5, rotationX: 0, rotationY: 0, rotationZ: 0, x: 0, y: 0, z: -500, time: 3});
						else
							Tweener.addTween(p, {scale: 0, x: 0, y: 0, z: 0, time: 3});
					}
				}
			}
			else if (tp.extra.roll == 1)
			{
				vpl.filters=[];
				tp.extra.roll=0;

				for (var ii:int=0; ii < 20; ii++)
				{
					for (var jj:int=0; jj < 5; jj++)
					{
						var pp:Plane=rootNode.getChildByName("plane" + ii.toString() + jj.toString()) as Plane;

						if (pp.name == str)
							Tweener.addTween(pp, {scale: 1, rotationX: -pp.extra.theta1, rotationY: pp.extra.theta2, rotationZ: 0, x: p.extra.x, y: p.extra.y, z: p.extra.z, time: 1, onComplete: function():void
								{
									move=true;
								}});
						else
							Tweener.addTween(p, {scale: 1, x: p.extra.x, y: p.extra.y, z: p.extra.z, time: 1});
					}
				}
			}
		}

		// リサイズ用関数
		private function onResize(e:Event):void
		{
			container.x=stage.stageWidth / 2;
			container.y=stage.stageHeight / 2;
			setBar();
		}

		// ローディングアニメーション用関数
		private function onloading(e:Event):void
		{
			if (e.target.alpha <= 0)
				loadingAlpha=0.05;
			if (e.target.alpha >= 1)
				loadingAlpha=-0.05;
			e.target.alpha+=loadingAlpha;
		}

		// バー作成用関数
		private function setBar():void
		{
			var g:Graphics=container.graphics;

			g.clear();
			g.beginFill(0xffffff, 1);
			g.drawRect(-stage.stageWidth / 2, stage.stageHeight / 2 - 70, stage.stageWidth, 70);
			g.drawRect(-stage.stageWidth / 2, -stage.stageHeight / 2, stage.stageWidth, 70);
			g.endFill();

			titleSp.x=stage.stageWidth / 2 - titleSp.width - 20;
			titleSp.y=stage.stageHeight / 2 - 70 + 2;
		}

		// フレームイベント用関数
		private function onFrame(e:Event):void
		{
			if (move == true)
			{
				// planeの位置を計算
				for (var i:int=0; i < 20; i++)
				{
					for (var j:int=0; j < 5; j++)
					{
						var p:Plane=rootNode.getChildByName("plane" + i.toString() + j.toString()) as Plane;

						if (i % 2 == 0)
						{
							p.extra.theta1+=0.2;
							p.extra.theta2+=0.2;

							if (p.extra.theta1 >= 360)
								p.extra.theta1=0;
							if (p.extra.theta2 >= 360)
								p.extra.theta2=0;

						}
						else
						{
							p.extra.theta1-=0.2;
							p.extra.theta2-=0.2;
							if (p.extra.theta1 <= -360)
								p.extra.theta1=0;
							if (p.extra.theta2 <= -360)
								p.extra.theta2=0;
						}

						var r:Number=p.extra.radius * Math.cos(p.extra.theta1 * Math.PI / 180);
						p.extra.y=p.y=p.extra.radius * Math.sin(p.extra.theta1 * Math.PI / 180);
						p.extra.x=p.x=r * Math.sin(p.extra.theta2 * Math.PI / 180);
						p.extra.z=p.z=r * Math.cos(p.extra.theta2 * Math.PI / 180);

						p.rotationX=-p.extra.theta1;
						p.rotationY=p.extra.theta2;
						p.rotationZ=0;
					}
				}
			}
			render.renderScene(scene, camera, viewport);
		}
	}
} 

Forked