分享:計算機圖形學期末作業!!利用WebGL的第三方庫three.js寫一個簡單的網頁版“我的世界小游戲”


這幾天一直在忙着期末考試,所以一直沒有更新我的博客,今天剛把我的期末作業完成了,心情澎湃,所以晚上不管怎么樣,我也要寫一篇博客紀念一下我上課都沒有聽,還是通過強大的度娘完成了我的作業的經歷。(當然作業不是百度來的,我只是百度了一些示例代碼的意思,怎么用!算了,越解釋萬一越黑呢!哈哈O(∩_∩)O哈哈~)

----------------------------------------------------------------分界線------------------------------------------------------------------

(順便請教一下,分界線應該怎么弄才好看,每次調半天才合適!!!)

工程開始:

  1、目標:利用WebGL的第三方js庫,three.js寫一個簡單的網頁版“我的世界小游戲”。

    (當時定了這個題目之后我就后悔了,我這個菜鳥做一個這個還是有點難度的。)

  2、准備工作:

    1)首先了解一下three.js,其次你要了解一個最簡單的demo的生成方式,這里我就轉載一篇我們博客園博友的文章:【three.js詳解之一】入門篇

       (我不知道能不能轉載博友的文章,我私信他了,但還是沒回,我相信他還是應該能接受的吧。)

      2)參考一下官方給出的一些three.js的例子,有些還是挺有意思的,【官方例子】

      3)其實還是要求一定的web基礎的,懂一些html,JavaScript。

  3、進行時:

    1)html部分我就不詳細講解了,我就講解一下重點的部分,首先我們需要引入兩個js文件,three.js和Detector.js,第二個js文件的作用:Detector是一個探測器,用來探測WebGL的支持情況。

 

1 <script>
2     if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
3 </script>

 

     2)我們需要搭建一個場景,在我轉載的博友的文章中,有詳細的說明,這里我也簡單的提一下。

      我把我的渲染器定義成了一個函數,然后通過函數的調用實現場景的布置。函數代碼如下:

      (很多的代碼我原來都不懂什么意思,注釋都是我百度每一條什么意思然后添加上去的,希望可以幫助到大家)

      這里有幾點需要注意:

      ①這里不是通過常規的添加html標簽進行網頁的設計,而是通過createElement的方法添加標簽。

      ②渲染器、相機camera、場景scene、光源light、物體object是基本的五個部分。

      ③對於我添加的五個button按鈕,他對應的有五個onclick事件,通過button的內容大家也不難看出來,其實每個事件對應的一個圖形,玩過我的世界的人都應該知道,里面的工具很多,但是我就簡單的添加了四個不一樣的形狀,因此我將五個method()函數封裝了起來,然后通過統一的onclick點擊調用實現形狀的切換。

      ④最下面有四個分別對鼠標和shift按鍵的監聽事件,字面意思很好理解,大家可以看一下,實現的函數將會在下面展示出來。

 1 <script>
 2                 function init(){
 3 
 4                 container = document.createElement( 'div' );//使用createElement創建一個div,就是整個頁面
 5                 document.body.appendChild( container );//添加子節點
 6 
 7                 var info = document.createElement( 'div' );//在大的div中創建第一個div,表示head部分,名字為info
 8                 info.style.position = 'absolute';
 9                 info.style.top = '10px';
10                 info.style.width = '100%';
11                 info.style.textAlign = 'center';
12                 info.innerHTML = '計算機圖形學作業:簡單模擬我的世界<br><strong>shift + click</strong>:移除圖形<br>' +
13                 '<button class="btn1" onclick="method1()">正方體</button><button class="btn2" onclick="method2()">球體</button>' +
14                 '<button class="btn3" onclick="method3()">長方體</button><button class="btn4" onclick="method4()">圓柱體</button>' +
15                 '<br><button class="btn5" onclick="method5()">預覽</button>';
16                 container.appendChild( info );//將創建的info添加到大的div中
17 
18                 camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );//設置透視投影的相機
19                 camera.position.set( 500, 800, 1300 );//設置相機坐標
20                 camera.lookAt( new THREE.Vector3() );//設置視野的中心坐標
21 
22                 scene = new THREE.Scene();//設置場景,場景是一個三維空間,用Scene類聲明一個對象scene
23                 // grid,定義畫布上的坐標格子
24                 var size = 500, step = 50;
25                 var geometry = new THREE.Geometry();//創建一個基本的幾何形狀
26                 for ( var i = - size; i <= size; i += step ) {
27                     geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
28                     geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
29                     geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
30                     geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
31                 }
32                 var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );
33                 //創建一個線條材質,線條顏色黑色,透明度0.2
34                 var line = new THREE.LineSegments( geometry, material );
35                 scene.add( line );
36                 raycaster = new THREE.Raycaster();
37                 mouse = new THREE.Vector2();
38                 var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
39                 geometry.rotateX( - Math.PI / 2 );
40                 plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
41                 scene.add( plane );
42                 objects.push( plane );
43                 // 創建環境光為灰色
44                 var ambientLight = new THREE.AmbientLight( 0x606060 );
45                 scene.add( ambientLight );
46                 //創建平行光為白色
47                 var directionalLight = new THREE.DirectionalLight( 0xffffff );
48                 directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
49                 scene.add( directionalLight );
50 
51                 renderer = new THREE.WebGLRenderer( { antialias: true } );//生成渲染器對象,鋸齒效果為true
52                 renderer.setClearColor( 0xf0f0f0 );
53                 renderer.setPixelRatio( window.devicePixelRatio );
54                 renderer.setSize( window.innerWidth, window.innerHeight );
55                 container.appendChild( renderer.domElement );
56                 document.addEventListener( 'mousemove', onDocumentMouseMove, false );//鼠標移動事件
57                 document.addEventListener( 'mousedown', onDocumentMouseDown, false );//鼠標點擊事件
58                 document.addEventListener( 'keydown', onDocumentKeyDown, false );//對shift按鍵的控制
59                 document.addEventListener( 'keyup', onDocumentKeyUp, false );//對shift按鍵的控制
60                 window.addEventListener( 'resize', onWindowResize, false );//窗口改變事件
61             }
62 
63 </script>

 

    可以先給大家看一看整個場景布置出來的效果:(很普通的一個格子狀)

    

     3)這里引出一個問題,我們在點擊選擇了圖形之后,我們需要一個選擇的圖形的預覽,就跟隨在你鼠標的左上方,時刻的提醒着你選擇的是什么圖形,說的有點抽象,我們看個實際圖形吧!旁邊那個虛虛的就是跟隨在鼠標左右的,左邊那個是實體,你的鼠標移動到那里,那個虛虛的就會跟隨到那里。現在我們就實現一個功能,就以正方體為例子吧!

      

    代碼如下:

 1 <script>
 2     function methodfollow1(){
 3                 // 這個幾何對象是鼠標在移動時候,跟隨鼠標顯示的幾何對象
 4                 rollOverGeo = new THREE.BoxGeometry( 50, 50, 50 );//創建一個盒狀幾何對象
 5                 rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
 6                 //創建一個色彩為紅色的材料,透明度為半透明
 7                 rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
 8                 //通過mesh方法把顏色應用到幾何對象上
 9                 scene.add( rollOverMesh );
10                 //最后把該立方體對象添加到場景scene中
11             }
12 </script>

     4)現在我們的跟隨預覽實現了,那么下面需要實現的就是我們添加到畫布格子中的一個個圖形了,還是以正方體為例子吧!直接看代碼吧。

      注意:里面引用了methodfollow1()函數,很好理解,每個圖形對應不同的實體和不同的跟隨預覽。還有一點需要注意是這個函數是你點擊了button出發的click事件(兩個)。

1 <script>
2    function method1(){
3                 methodfollow1();
4                 // 實體對象,就是鼠標點擊確定之后的實體對象,並且實體對象的圖片引入
5                 cubeGeo = new THREE.BoxGeometry( 50, 50, 50 );
6                 cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } );
7             } 
8 </script>   

     5)正方體的實體和跟隨預覽的函數都寫好了,這里需要講兩點:

       ①實體的四個函數和跟隨預覽的四個函數(當然你有多少個形狀就寫多少個函數,也可以統一封裝成類進行調用),定義函數的方法是一樣的,就像高中的同理可得。但是用到的圖形函數不一樣,我給大家簡單列舉幾個吧,大家也可以去看看這個:點擊我,關於函數的參數,大家可以自己去百度一下,這樣自己理解的更快一點而且深刻。

 1 <script>
 2     THREE.CubeGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)//立方體
 3     THREE.PlaneGeometry(width, height, widthSegments, heightSegments)//平面
 4     THREE.SphereGeometry(radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength)//球體
 5     THREE.CircleGeometry(radius, segments, thetaStart, thetaLength)//圓形
 6     THREE.CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded)//圓柱體
 7     THREE.TetrahedronGeometry(radius, detail)//正四面體
 8     THREE.OctahedronGeometry(radius, detail)//正八面體
 9     THREE.IcosahedronGeometry(radius, detail)//正二十面體
10     THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)//圓環面
11 </script>

      ②每一個button的click事件對應的method函數都需要先進行調用methodfollow函數,因為創建跟隨預覽是在創建實體之先。

     6)接下來講一講前面留下的四個監聽事件。功能分別如下:

1 onDocumentMouseMove:鼠標移動時發生的事件,主要是跟隨預覽
2 onDocumentMouseDown:鼠標點擊確定發生的事件,主要是實體
3 onDocumentKeyDown
4 onDocumentKeyUp    :這兩個函數是對shift的控制,在我們添加錯了圖形之后,可以按下shift鍵來進行錯誤圖形的刪除

       實現的代碼如下(實現的方法很多種,大家可以自由發揮):

 1 <script>
 2                 function onDocumentMouseMove( event ) {
 3                 event.preventDefault();//取消事件的默認動作
 4                 mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );
 5                 raycaster.setFromCamera( mouse, camera );
 6                 var intersects = raycaster.intersectObjects( objects );
 7                 if ( intersects.length > 0 ) {
 8                     var intersect = intersects[ 0 ];
 9                     rollOverMesh.position.copy( intersect.point ).add( intersect.face.normal );
10                     rollOverMesh.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
11                 }
12                 render();
13             }
14             function onDocumentMouseDown( event ) {
15                 event.preventDefault();
16                 mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );
17                 raycaster.setFromCamera( mouse, camera );
18                 var intersects = raycaster.intersectObjects( objects );
19                 if ( intersects.length > 0 ) {
20                     var intersect = intersects[ 0 ];
21                     // delete cube
22                     if ( isShiftDown ) {
23                         if ( intersect.object != plane ) {
24                             scene.remove( intersect.object );
25                             objects.splice( objects.indexOf( intersect.object ), 1 );
26                         }
27                     // create cube
28                     } else {
29                         var voxel = new THREE.Mesh( cubeGeo, cubeMaterial );
30                         voxel.position.copy( intersect.point ).add( intersect.face.normal );
31                         voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
32                         scene.add( voxel );
33                         objects.push( voxel );
34                     }
35                     render();
36                 }
37             }
38             function onDocumentKeyDown( event ) {
39                 switch( event.keyCode ) {
40                     case 16: isShiftDown = true; break;
41                 }
42             }
43             function onDocumentKeyUp( event ) {
44                 switch ( event.keyCode ) {
45                     case 16: isShiftDown = false; break;
46                 }
47             }
48 </script>

    7)這樣一來,我們基本的大模塊都已經完成了,那么接下來我們就看看我們的成果吧,很激動!(左邊的四個形狀的預覽,是我后面添加的,利用幾個html標簽就行了)

 

 

 

 

 

 

 4、結束總結

    1、我把我的源代碼貼出來吧!(可千萬不要問我:我復制了源代碼為什么預覽不出來啊!!)

 1 <!DOCTYPE html>
 2 <html lang="en">
 3     <head>
 4         <title>three.js webgl - interactive - voxel painter</title>
 5         <meta charset="utf-8">
 6         <title>opengl實現我的世界</title>
 7         <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 8         <style>
 9  body {
 10  font-family: Monospace;
 11  background-color: #f0f0f0;
 12  margin: 0px;
 13  overflow: hidden;
 14             }
 15  #aa{
 16  font-size: 10px;
 17             }
 18 
 19  #oldie { background-color: #ddd !important }
 20         </style>
 21     </head>
 22     <body>
 23         <a id="aa">正方體</a>
 24         <img src="textures/zhengfangti.png">
 25         <a id="aa">球體</a>
 26         <img src="textures/qiuti.png">
 27         <a id="aa">長方體</a>
 28         <img src="textures/changfangti.png">
 29         <a id="aa">圓柱體</a>
 30         <img src="textures/yuanzhuti.png">
 31         <script src="../build/three.js"></script>
 32         <script src="js/Detector.js"></script>
 33         <script src="js/jquery-2.2.4.min.js"></script>
 34         <script>
 35             if ( ! Detector.webgl ) Detector.addGetWebGLMessage();  36             //detector是一個探測器,引用了detector.js,用來探測webgl的支持情況
 37 
 38             var container;  39             var camera, scene, renderer;  40             var plane, cube;  41             var mouse, raycaster, isShiftDown = false;  42 
 43             var rollOverMesh, rollOverMaterial;  44             var cubeGeo, cubeMaterial;  45 
 46             var objects = [];  47 
 48  init();  49  render();//渲染
 50 
 51 
 52 
 53             function init(){  54 
 55  container = document.createElement( 'div' );//使用createElement創建一個div,就是整個頁面
 56  document.body.appendChild( container );//添加子節點
 57 
 58                 var info = document.createElement( 'div' );//在大的div中創建第一個div,表示head部分,名字為info
 59  info.style.position = 'absolute';  60  info.style.top = '10px';  61  info.style.width = '100%';  62  info.style.textAlign = 'center';  63  info.innerHTML = '計算機圖形學作業:簡單模擬我的世界<br><strong>shift + click</strong>:移除圖形<br>' +
 64                 '<button class="btn1" onclick="method1()">正方體</button><button class="btn2" onclick="method2()">球體</button>' +
 65                 '<button class="btn3" onclick="method3()">長方體</button><button class="btn4" onclick="method4()">圓柱體</button>' +
 66                 '<br><button class="btn5" onclick="method5()">預覽</button>';  67  container.appendChild( info );//將創建的info添加到大的div中
 68 
 69  camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );//設置透視投影的相機
 70  camera.position.set( 500, 800, 1300 );//設置相機坐標
 71  camera.lookAt( new THREE.Vector3() );//設置視野的中心坐標
 72 
 73  scene = new THREE.Scene();//設置場景,場景是一個三維空間,用Scene類聲明一個對象scene
 74                 // grid,定義畫布上的坐標格子
 75                 var size = 500, step = 50;  76                 var geometry = new THREE.Geometry();//創建一個基本的幾何形狀
 77                 for ( var i = - size; i <= size; i += step ) {  78  geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );  79  geometry.vertices.push( new THREE.Vector3( size, 0, i ) );  80  geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );  81  geometry.vertices.push( new THREE.Vector3( i, 0, size ) );  82  }  83                 var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );  84                 //創建一個線條材質,線條顏色黑色,透明度0.2
 85                 var line = new THREE.LineSegments( geometry, material );  86  scene.add( line );  87  raycaster = new THREE.Raycaster();  88  mouse = new THREE.Vector2();  89                 var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );  90  geometry.rotateX( - Math.PI / 2 );  91  plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );  92  scene.add( plane );  93  objects.push( plane );  94                 // 創建環境光為灰色
 95                 var ambientLight = new THREE.AmbientLight( 0x606060 );  96  scene.add( ambientLight );  97                 //創建平行光為白色
 98                 var directionalLight = new THREE.DirectionalLight( 0xffffff );  99  directionalLight.position.set( 1, 0.75, 0.5 ).normalize(); 100  scene.add( directionalLight ); 101 
102  renderer = new THREE.WebGLRenderer( { antialias: true } );//生成渲染器對象,鋸齒效果為true
103  renderer.setClearColor( 0xf0f0f0 ); 104  renderer.setPixelRatio( window.devicePixelRatio ); 105  renderer.setSize( window.innerWidth, window.innerHeight ); 106  container.appendChild( renderer.domElement ); 107  document.addEventListener( 'mousemove', onDocumentMouseMove, false );//鼠標移動事件
108  document.addEventListener( 'mousedown', onDocumentMouseDown, false );//鼠標點擊事件
109  document.addEventListener( 'keydown', onDocumentKeyDown, false );//對shift按鍵的控制
110  document.addEventListener( 'keyup', onDocumentKeyUp, false );//對shift按鍵的控制
111  window.addEventListener( 'resize', onWindowResize, false );//窗口改變事件
112  } 113 
114 
115 
116             //把創建鼠標跟隨幾何圖形和實體圖形都抽象成函數,通過點擊事件進行調用
117             function method1(){ 118  methodfollow1(); 119                 // 實體對象,就是鼠標點擊確定之后的實體對象,並且實體對象的圖片引入
120  cubeGeo = new THREE.BoxGeometry( 50, 50, 50 ); 121  cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } ); 122  } 123             function method2(){ 124  methodfollow2(); 125                 // 實體對象,就是鼠標點擊確定之后的實體對象,並且實體對象的圖片引入
126  cubeGeo = new THREE.SphereGeometry( 50, 10, 10 ); 127  cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x4D662D/*, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" )*/ } ); 128  } 129             function method3(){ 130  methodfollow3(); 131                 // 實體對象,就是鼠標點擊確定之后的實體對象,並且實體對象的圖片引入
132  cubeGeo = new THREE.CubeGeometry( 50, 100, 50 ); 133  cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x4D662D, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } ); 134  } 135             function method4(){ 136  methodfollow4(); 137                 // 實體對象,就是鼠標點擊確定之后的實體對象,並且實體對象的圖片引入
138  cubeGeo = new THREE.CylinderBufferGeometry( 25,25, 100, 50 ,50); 139  cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x4D662D, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } ); 140  } 141             function method5(){ 142  window.open("newwindows.html","_blank","resizable=yes,scrollbars=yes,titlebar=yes,windth=800,height=800"); 143  } 144 
145             function methodfollow1(){ 146                 // 這個幾何對象是鼠標在移動時候,跟隨鼠標顯示的幾何對象
147  rollOverGeo = new THREE.BoxGeometry( 50, 50, 50 );//創建一個盒狀幾何對象
148  rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } ); 149                 //創建一個色彩為紅色的材料,透明度為半透明
150  rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial ); 151                 //通過mesh方法把顏色應用到幾何對象上
152  scene.add( rollOverMesh ); 153                 //最后把該立方體對象添加到場景scene中
154  } 155             function methodfollow2(){ 156                 // 這個幾何對象是鼠標在移動時候,跟隨鼠標顯示的幾何對象
157  rollOverGeo = new THREE.SphereGeometry( 50, 10, 10 );//創建一個盒狀幾何對象
158  rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } ); 159                 //創建一個色彩為紅色的材料,透明度為半透明
160  rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial ); 161                 //通過mesh方法把顏色應用到幾何對象上
162  scene.add( rollOverMesh ); 163                 //最后把該立方體對象添加到場景scene中
164  } 165             function methodfollow3(){ 166                 // 這個幾何對象是鼠標在移動時候,跟隨鼠標顯示的幾何對象
167  rollOverGeo = new THREE.CubeGeometry( 50, 100, 50 );//創建一個盒狀幾何對象
168  rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } ); 169                 //創建一個色彩為紅色的材料,透明度為半透明
170  rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial ); 171                 //通過mesh方法把顏色應用到幾何對象上
172  scene.add( rollOverMesh ); 173                 //最后把該立方體對象添加到場景scene中
174  } 175             function methodfollow4(){ 176                 // 這個幾何對象是鼠標在移動時候,跟隨鼠標顯示的幾何對象
177  rollOverGeo = new THREE.CylinderGeometry( 25,25 ,100, 50,50 );//創建一個盒狀幾何對象
178  rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } ); 179                 //創建一個色彩為紅色的材料,透明度為半透明
180  rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial ); 181                 //通過mesh方法把顏色應用到幾何對象上
182  scene.add( rollOverMesh ); 183                 //最后把該立方體對象添加到場景scene中
184  } 185 
186 
187             function onWindowResize() { 188 
189  camera.aspect = window.innerWidth / window.innerHeight; 190  camera.updateProjectionMatrix(); 191 
192  renderer.setSize( window.innerWidth, window.innerHeight ); 193 
194  } 195 
196             function onDocumentMouseMove( event ) { 197  event.preventDefault();//取消事件的默認動作
198  mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 ); 199  raycaster.setFromCamera( mouse, camera ); 200                 var intersects = raycaster.intersectObjects( objects ); 201                 if ( intersects.length > 0 ) { 202                     var intersect = intersects[ 0 ]; 203  rollOverMesh.position.copy( intersect.point ).add( intersect.face.normal ); 204  rollOverMesh.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 ); 205  } 206  render(); 207  } 208             function onDocumentMouseDown( event ) { 209  event.preventDefault(); 210  mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 ); 211  raycaster.setFromCamera( mouse, camera ); 212                 var intersects = raycaster.intersectObjects( objects ); 213                 if ( intersects.length > 0 ) { 214                     var intersect = intersects[ 0 ]; 215                     // delete cube
216                     if ( isShiftDown ) { 217                         if ( intersect.object != plane ) { 218  scene.remove( intersect.object ); 219  objects.splice( objects.indexOf( intersect.object ), 1 ); 220  } 221                     // create cube
222  } else { 223                         var voxel = new THREE.Mesh( cubeGeo, cubeMaterial ); 224  voxel.position.copy( intersect.point ).add( intersect.face.normal ); 225  voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 ); 226  scene.add( voxel ); 227  objects.push( voxel ); 228  } 229  render(); 230  } 231  } 232             function onDocumentKeyDown( event ) { 233                 switch( event.keyCode ) { 234                     case 16: isShiftDown = true; break; 235  } 236  } 237             function onDocumentKeyUp( event ) { 238                 switch ( event.keyCode ) { 239                     case 16: isShiftDown = false; break; 240  } 241  } 242             function render() { 243 
244  renderer.render( scene, camera ); 245 
246  } 247 
248         </script>
249     </body>
250 </html>
源代碼

    2、其實這個小程序沒什么多大的難度,主要是娛樂一下,可能有些大神能做出更好的,當然,我要是做的很好,我為什么還在上學呢,哈哈!

    3、這里又一個小小的私心,每次看到博客園的很多大牛,都是粉絲很多很多,我看了看我自己的只有3個,額,我的意思是希望大家相互關注一下,以后有什么好的博客,大家也能及時的看到!嘿嘿,不過這不是打廣告,只是我感覺每次有個人關注我之后,我都興奮了好幾個小時,然后我也會關注他。

    4、大家有什么好的建議和意見都可以提出來,我都虛心接受的,我接觸的東西肯定沒有廣大的博友多,希望大家相互照顧!謝謝。看了看時間:2016年6月25日凌晨3:34,從11點多開始寫,改了很多地方,怕自己的東西大家看了不喜歡,我會努力的!該睡覺了,10點鍾還有課呢,頭疼/(ㄒoㄒ)/~~

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM