[flash 3D]flash CS4 3D功能加PV3D的建築物內部旋轉

LINEで送る
[`evernote` not found]

有點落落長的標題….
大概也說完這篇的CODE要做的事了啦^^”

為什麼不全部都用PV3D勒!?
因為PV3D的定位真的是太麻煩了
所以能不用外部LOAD近來的東西我就儘量避開囉

flash CS4 3D功能的部分是建築物的各樓層
PV3D的部分就是LOGO們
按左右的按鈕可以控制旋轉
懶得弄DEMO了…等正式上線在回來補上吧!!

為了分開各層的深度跟旋轉角度…等
所以每一層的LOGO都獨立一個BasicView
在addChild時也要注意一下深度的排列(跟各樓層的MC交叉排列)

每個建築的內部跟放的LOGO數量都不一樣
所以除了用biruNaka.as控制相同的部份外
各建築還要多用個AS(biru_nakaX.as)做主要的控制

biruNaka.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package {
 
	import flash.events.*;
	import flash.display.MovieClip;
	import caurina.transitions.Tweener;	
	import flash.utils.Timer;
 
	import caurina.transitions.properties.ColorShortcuts;
	ColorShortcuts.init();
 
	public class biruNaka extends MovieClip {
		var mod:ModelLocator = ModelLocator.getInstance(); 
		var citymod:CityLocator = CityLocator.getInstance();
		var lBtnX:Number;
		var rBtnX:Number;
		var btnY:Number;
		var _btn_left:btn_left = new btn_left();
		var _btn_right:btn_right = new btn_right();
 
		public function biruNaka() {
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event) {
			_btn_left.alpha = _btn_right.alpha = 0;
			addChild(_btn_left);
			addChild(_btn_right);
 
			btnY = (this.height - _btn_left.height - this.y) / 2;
			_btn_left.y = _btn_right.y = btnY;
 
			lBtnX = this.x - _btn_left.width - 10 - citymod.cityNaka_arr_d3d[mod.now_3d][0] +citymod.cityNaka_fix_arr[mod.now_3d];
			rBtnX = this.x + this.width + 10 - citymod.cityNaka_arr_d3d[mod.now_3d][0] + citymod.cityNaka_fix_arr[mod.now_3d];
			_btn_left.x = lBtnX + 5;
			_btn_right.x = rBtnX - 5;
 
			Tweener.addTween(_btn_left, { x:lBtnX, alpha:1, time:0.5, transition:"easeOutBack", delay:1 } );
			Tweener.addTween(_btn_right, { x:rBtnX, alpha:1, time:0.5, transition:"easeOutBack", delay:1 } );
		}
	}
}

biru_naka1.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package {
 
	import flash.events.*;
	import flash.display.MovieClip;
	import caurina.transitions.Tweener;	
	import flash.utils.Timer;
 
	import org.papervision3d.objects.primitives.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.events.*
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.view.layer.ViewportLayer;
	import org.papervision3d.materials.BitmapAssetMaterial;
	import org.papervision3d.view.layer.util.ViewportLayerSortMode;
 
	import caurina.transitions.properties.ColorShortcuts;
	ColorShortcuts.init();
 
	public class biru_naka1 extends biruNaka {
		var view:BasicView;
		var _kakudou:Array = new Array(0, 90, 270);
		var now_kakudou:int = 0;
		var now_kakudou_num:int = 0;
 
		var logolist:XMLList;
		var floorArr:XMLList;
		var radius:int = 187;//半徑
 
		public function biru_naka1() {
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init3DEngine():void{
			for (var i = 0; i < floorArr.length(); i++ ) {
				var _view:BasicView = new BasicView(0, 0, true, true, "Target");
				var ff:MovieClip = this.getChildByName("f" + (i + 1)) as MovieClip;
				_view.x = -405;
				_view.y = 78 * i-340;
				_view.name = "view" + i;
				_view.camera.y = 300;
				_view.camera.z = -900;
				_view.viewport.buttonMode = true;
				addChildAt(_view, getChildIndex(ff) + 1);
			}
 
			this.addEventListener(Event.ENTER_FRAME, onEventRender3D);
		}
 
		private function init(e:Event) {
			logolist = mod.bland_XML.logo.(@category == citymod.biruArrEn[mod.now_3d]);
			floorArr = mod.bland_XML.floor.(@category == citymod.biruArrEn[mod.now_3d]);
			_btn_left.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent) { initKakudou(false); } );
			_btn_right.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent) { initKakudou(true); } );
 
			init3DEngine();
			makeLogo();
		}
 
		private function floorMove(b:Boolean):void {
			for (var i = 1; i <= floorArr.length(); i++) {
				var ff:MovieClip=this.getChildByName("f"+i) as MovieClip;
				if (b) {
					Tweener.addTween(ff.ss, { rotation:_kakudou[now_kakudou_num], time:1, transition:"linear" } );
				}else {
					_kakudou[now_kakudou_num] > 0	?	Tweener.addTween(ff.ss, { rotation:_kakudou[now_kakudou_num] - 360, time:1, transition:"linear" } ):
														Tweener.addTween(ff.ss, { rotation:_kakudou[now_kakudou_num] , time:1, transition:"linear" } );
				}
 
			}
 
		}
 
		private function moveLogo3D() {
			for (var i = 0; i < floorArr.length(); i++) {
				var _view:BasicView = getChildByName("view" + i) as BasicView;
				var logoRootNode:DisplayObject3D = _view.scene.getChildByName("_logoRootNode") as DisplayObject3D;
				var dang:Number = Math.PI * 2 / floorArr[i];
				Tweener.addTween(logoRootNode, { 
					rotationY: now_kakudou_num * dang * 180 / Math.PI -30, 
					time:1, 
					transition:"linear"
					} );
			}
		}
 
		private function initKakudou(b:Boolean) {
			if (b) {
				now_kakudou_num++;
				now_kakudou_num = now_kakudou_num < _kakudou.length? now_kakudou_num : now_kakudou_num - _kakudou.length;
				//now_kakudou += _kakudou[now_kakudou_num];
			}else {
				now_kakudou_num--;
				now_kakudou_num = now_kakudou_num < 0?now_kakudou_num + _kakudou.length:now_kakudou_num;
				//now_kakudou -= _kakudou[now_kakudou_num];
			}
			moveLogo3D();
			floorMove(b);
		}
 
		private function makeLogo() {
			var _start:int = 0;
			for (var i = 0; i < floorArr.length(); i++) {
				var dang:Number = Math.PI * 2 / floorArr[i];
				var _view:BasicView = getChildByName("view" + i) as BasicView;
				var logoRootNode:DisplayObject3D = new DisplayObject3D();
				logoRootNode.name = "_logoRootNode";
				_view.scene.addChild(logoRootNode);
 
				for (var j = 1; j <= floorArr[i]; j++) {
					var _ang:Number = j * dang;
					var _img:String = mod.rooturl + "/" + logolist[_start].img_path;			
					var _bmpMat:BitmapFileMaterial = new BitmapFileMaterial(_img);
					_bmpMat.doubleSided = true; //雙面模式
					_bmpMat.smooth = true; // 平滑化
					var _plane	:Plane = new Plane(_bmpMat, 100, 100, 2, 2);
					_plane.useOwnContainer = true;
					_plane.alpha = 0;
					_plane.x = Math.cos(_ang) * radius;
					_plane.z = Math.sin(_ang) * radius;
					//trace(_start,j,_kakudou[j - 1]);
					_plane.rotationY = 270 - (_ang * 180 / Math.PI);
					logoRootNode.addChild(_plane);
					Tweener.addTween(_plane,{
												alpha		: 1,
												time		: 0.3,
												transition	:"linear",
												delay		:0.5
											}
										);
					_start++;
				}
				logoRootNode.rotationY = -30;
			}
		}
 
		private function onEventRender3D(e:Event):void {
			for (var i = 0; i < floorArr.length(); i++) {
				var _view:BasicView = getChildByName("view" + i) as BasicView;
				_view.singleRender();
			}
		}
	}
}