イナヅマTVログ

ActionScript 3, 筒状に並べた画像を回転させる

| 0件のコメント

前回同様 Advanced ActionScript 3.0 Animation を参考に画像を筒状に並べて3D回転させてみた。

サンプルでは Rotate Carousel(回転木馬)と名前がついていた。
サンプルは Shape を並べていて表裏が関係ない、Bitmap に置換えるときに注意が必要。

Rotate Carousel - 1

Flash Player 10 で追加された3D関連のクラスを把握するのに時間がかかりそうな予感。
Matrix3d, Vector3D, PerspectiveProjection が重要な働きをしている。

Demo : Rotate Carousel v.1 - Flash Player 10 が必要です。

ポップアップされたウインドウをリサイズすると面白い。

もう一つ。
PerspectiveProjection.fieldOfView を小さくしたものを作った。

Rotate Carousel 2

Demo : Rotate Carousel v.2 - Flash Player 10 が必要です。

全ての画像が見えるようになると、手前の画像が表を向いている必要があるので、v.2 では rotationY を +180 している。
PerspectiveProjection.fieldOfView は魚眼効果を出す働きがある。
値が大きいと効果も大きくなる、0 から 180 の間で設定できる。

package {
 
import flash.display.StageAlign;
import flash.display.StageScaleMode;
 
import flash.events.Event;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Bitmap;
import flash.geom.Vector3D;
import flash.geom.Point;
 
[SWF(backgroundColor=0xFFFFFF, frameRate='24')]
 
public class RotateCarousel extends Sprite {
 
	[Embed(source="dim1.png")]
	private var dim1:Class;
	[Embed(source="dim2.png")]
	private var dim2:Class;
	[Embed(source="dim3.png")]
	private var dim3:Class;
	[Embed(source="dim4.png")]
	private var dim4:Class;
	[Embed(source="dim5.png")]
	private var dim5:Class;
	[Embed(source="dim6.png")]
	private var dim6:Class;
 
	private var _images:Array;
	private var _num:uint;
	private var _surfaces:Array;
	private var _sprite:Sprite;
	private var _radius:uint = 300;
 
	public function RotateCarousel()
	{
		super();
		stage.addEventListener(Event.RESIZE, resizeHandler);
		stage.align = StageAlign.TOP_LEFT;
		stage.scaleMode = StageScaleMode.NO_SCALE;
 
		root.transform.perspectiveProjection.fieldOfView = 50;// v.1 : 130
 
		_sprite = new Sprite();
		_sprite.x = stage.stageWidth / 2;
		_sprite.y = stage.stageHeight / 2;
		_sprite.z = 300;//v.1 : 0
		addChild(_sprite);
 
		_images = [dim1, dim2, dim3, dim4, dim5, dim6];
		_num = _images.length;
		var n:uint = _num;
 
		_surfaces = [];
 
		for (var i:int = 0; i < n; i++)
		{
			var angle:Number = Math.PI * 2 / n * i;
			var s:Sprite = makeSurface(i);
			s.x = Math.cos(angle) * _radius;
			s.z = Math.sin(angle) * _radius;
			s.rotationY = -360 / n * i + 90;
			s.rotationY += 180;//v.1 : 0
			_surfaces[_surfaces.length] = s;
		}
 
		sortSurfaces();
		addEventListener( Event.ENTER_FRAME, enterFrameHandler );
	}
 
	private function makeSurface(n:uint):Sprite
	{
		var d:Bitmap = new _images[n]() as Bitmap;
		var s:Sprite = new Sprite();
		s.addChild(d)
		d.x = -100;
		d.y = -100;
 
		_sprite.addChild(s);
		return s;
	}
 
	private function resizeHandler(event:Event):void
	{
		root.transform.perspectiveProjection.projectionCenter = new Point(stage.stageWidth / 2, stage.stageHeight / 2);
		_sprite.x = stage.stageWidth / 2;
		_sprite.y = stage.stageHeight / 2;
	}
 
	private function enterFrameHandler(event:Event):void
	{
		_sprite.rotationY += (stage.stageWidth / 2 - mouseX) * .01;
		_sprite.y += (mouseY - _sprite.y) * .1;
		sortSurfaces();
	}
 
	private function sortSurfaces():void
	{
		_surfaces.sort(depthSort);
		for (var i:int = 0; i < _surfaces.length; i++)
		{
			_sprite.addChildAt(_surfaces[i] as Sprite, i);
		}
	}
 
	private function depthSort(objA:DisplayObject, objB:DisplayObject):int
	{
		var posA:Vector3D = objA.transform.matrix3D.position;
		posA = _sprite.transform.matrix3D.deltaTransformVector(posA);
		var posB:Vector3D = objB.transform.matrix3D.position;
		posB = _sprite.transform.matrix3D.deltaTransformVector(posB);
		return posB.z - posA.z;
	}
 
}
 
}

TextMate + Flex SDK 3.3

コメントを残す

必須欄は * がついています


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください