近來在學習Flash的3D技術,現在我看過的就PV3D 與Away3D這兩個開源框架,感覺還不錯,好像Away3D的效果好點,但效率不如PV3D,PV3D算是亻為(不會用五筆打這個字-_-,我機子里又沒拼音輸入,將就下吧!)3D,不管這么多了,做個東西練練手,先看效果:
[url=http://www.jiangzone.com.cn/jiang/3dmusic/soundtest.swf]這里看看效果![/url]
這個程序很簡單到沒無簡單了,就只是用了PV3D框架中的Cube的3D對象,一口氣生成64個放在數組里待用,之后用Flash里的聲音類加載并播放聲音,之后在ENTER_FRAME事件里檢測當前聲音的頻譜,之后根據頻譜的高低來調整Cube格子的高低,在Flash里獲取的聲音頻譜有512個Float數據,代表512級頻譜,而前256級為LeftChangle,后256級為RightChangle,由于如果生成256個3D對象的話,對CPU來說是個考驗,所以就折中間隔抽取64個頻段來顯示,由于懶于寫代碼了,就只寫了LeftChangle的頻譜。
以下是代碼:
1 //************導入需要用到的類
2 import flash.display.Sprite;
3 import org.papervision3d.scenes.Scene3D;
4 import org.papervision3d.cameras.FreeCamera3D;
5 import org.papervision3d.objects.Cube;
6 import org.papervision3d.materials.MaterialsList;
7 import org.papervision3d.materials.WireframeMaterial;
8 import org.papervision3d.materials.ColorMaterial;
9 import org.papervision3d.cameras.Camera3D;
10 import org.papervision3d.objects.Plane;
11
12 //************定義需要用到的對象
13 var cont:Sprite;
14 var scene:Scene3D;
15 var camera:FreeCamera3D;
16 var ml:MaterialsList;
17 var material:ColorMaterial;
18 var cubeArr:Array;
19
20 //***********設置放置3D東東的容器
21 cont = new Sprite();
22 cont.x = 150;
23 cont.y = 120;
24 this.addChild(cont);
25
26 //******設置一個3D場景,并設置好Camera的位置與角度
27 scene = new Scene3D(cont);
28 camera = new FreeCamera3D();
29 camera.z = 1200;
30 camera.x = 100;
31 camera.y = 700;
32 camera.rotationX = -30;
33 camera.rotationY = 180;
34 camera.focus = 100;
35 camera.zoom = 10;
36
37 //***********定義一個存放所有格子的數組
38 cubeArr = new Array();
39
40 //定義一個顏色材質與材質列表,用于應用于格子的6個面的貼圖
41 material = new ColorMaterial(0x096288);
42 ml = new MaterialsList();
43 ml.addMaterial(material,"front");
44 ml.addMaterial(material,"back");
45 ml.addMaterial(material,"top");
46 ml.addMaterial(material,"bottom");
47 ml.addMaterial(material,"left");
48 ml.addMaterial(material,"right");
49
50 var i:int = 0;
51 var j:int = 0;
52
53 //生成64個小格子并排列好位置
54 for(;i<64;i++){
55 ml.addMaterial(new ColorMaterial(0xB9DFCF),"top");
56 var c:Cube = new Cube(ml,20,20,20);
57 c.x = (i % 8) * (20 + 5);
58 c.z = (j % 8) * (20 + 5);
59 (i % 8 == 0) ? j++:j=j;
60 cubeArr[i] = c;
61 scene.addChild(c);
62 }
63
64 //創建一個面板,設置好位置放在小格子隊列的下面(地板)
65 var plane:Plane = new Plane(new WireframeMaterial(0xaaaaaa),300,300,7,7);
66 plane.rotationX = -90;
67 plane.y = -50;
68 plane.x = 70;
69 plane.z = 60;
70 scene.addChild(plane);
71
72 //以上是3D部分,以下是聲音部分
73 //建立一個字節數組用于存放獲取到的頻譜信息
74 var bArr:ByteArray = new ByteArray();
75 //讀取聲音文件并播放
76 var req:URLRequest = new URLRequest("a.mp3");
77 var sound:Sound = new Sound(req);
78 sound.play();
79
80 //添加一個事件偵聽器
81 this.addEventListener(Event.ENTER_FRAME,onEnter);
82
83 function onEnter(e:Event):void{
84 //獲取當前聲音頻譜,將數據存放在bArr里面。
85 //true為頻譜模式,0為采樣率代號
86 SoundMixer.computeSpectrum(bArr,true,0);
87 i=0;
88 //讀取前256個數據,即Left聲道的頻譜
89 for(;i<256;i++){
90 var temp:Number = bArr.readFloat();
91 //間隔4個數據中獲取一個顯示
92 if(i % 4 == 0){
93 //從數組中獲取相應的格子
94 var c:Cube = cubeArr[i/4] as Cube;
95 //設置格子在三維坐標中的高。
96 //由于頻譜數據是0-1,所以將其放大100倍
97 c.y = temp * 100;
98 }
99 }
100 //鏡頭旋轉移動
101 camera.moveLeft(12);
102 camera.rotationY += 0.6;
103 scene.renderCamera(camera);
104 }
posted on 2008-07-29 14:16
姜大叔 閱讀(1456)
評論(1) 編輯 收藏 所屬分類:
Flash/Flex