这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历。(当然作业不是百度来的,我只是百度了一些示例代码的意思,怎么用!算了,越解释万一越黑呢!哈哈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. function init(){
  52.  
  53. container = document.createElement( 'div' );//使用createElement创建一个div,就是整个页面
  54. document.body.appendChild( container );//添加子节点
  55.  
  56. var info = document.createElement( 'div' );//在大的div中创建第一个div,表示head部分,名字为info
  57. info.style.position = 'absolute';
  58. info.style.top = '10px';
  59. info.style.width = '100%';
  60. info.style.textAlign = 'center';
  61. info.innerHTML = '计算机图形学作业:简单模拟我的世界<br><strong>shift + click</strong>:移除图形<br>' +
  62. '<button class="btn1" onclick="method1()">正方体</button><button class="btn2" onclick="method2()">球体</button>' +
  63. '<button class="btn3" onclick="method3()">长方体</button><button class="btn4" onclick="method4()">圆柱体</button>' +
  64. '<br><button class="btn5" onclick="method5()">预览</button>';
  65. container.appendChild( info );//将创建的info添加到大的div中
  66.  
  67. camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );//设置透视投影的相机
  68. camera.position.set( 500, 800, 1300 );//设置相机坐标
  69. camera.lookAt( new THREE.Vector3() );//设置视野的中心坐标
  70.  
  71. scene = new THREE.Scene();//设置场景,场景是一个三维空间,用Scene类声明一个对象scene
  72. // grid,定义画布上的坐标格子
  73. var size = 500, step = 50;
  74. var geometry = new THREE.Geometry();//创建一个基本的几何形状
  75. for ( var i = - size; i <= size; i += step ) {
  76. geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
  77. geometry.vertices.push( new THREE.Vector3( size, 0, i ) );
  78. geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
  79. geometry.vertices.push( new THREE.Vector3( i, 0, size ) );
  80. }
  81. var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );
  82. //创建一个线条材质,线条颜色黑色,透明度0.2
  83. var line = new THREE.LineSegments( geometry, material );
  84. scene.add( line );
  85. raycaster = new THREE.Raycaster();
  86. mouse = new THREE.Vector2();
  87. var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
  88. geometry.rotateX( - Math.PI / 2 );
  89. plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
  90. scene.add( plane );
  91. objects.push( plane );
  92. // 创建环境光为灰色
  93. var ambientLight = new THREE.AmbientLight( 0x606060 );
  94. scene.add( ambientLight );
  95. //创建平行光为白色
  96. var directionalLight = new THREE.DirectionalLight( 0xffffff );
  97. directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
  98. scene.add( directionalLight );
  99.  
  100. renderer = new THREE.WebGLRenderer( { antialias: true } );//生成渲染器对象,锯齿效果为true
  101. renderer.setClearColor( 0xf0f0f0 );
  102. renderer.setPixelRatio( window.devicePixelRatio );
  103. renderer.setSize( window.innerWidth, window.innerHeight );
  104. container.appendChild( renderer.domElement );
  105. document.addEventListener( 'mousemove', onDocumentMouseMove, false );//鼠标移动事件
  106. document.addEventListener( 'mousedown', onDocumentMouseDown, false );//鼠标点击事件
  107. document.addEventListener( 'keydown', onDocumentKeyDown, false );//对shift按键的控制
  108. document.addEventListener( 'keyup', onDocumentKeyUp, false );//对shift按键的控制
  109. window.addEventListener( 'resize', onWindowResize, false );//窗口改变事件
  110. }
  111.  
  112. //把创建鼠标跟随几何图形和实体图形都抽象成函数,通过点击事件进行调用
  113. function method1(){
  114. methodfollow1();
  115. // 实体对象,就是鼠标点击确定之后的实体对象,并且实体对象的图片引入
  116. cubeGeo = new THREE.BoxGeometry( 50, 50, 50 );
  117. cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } );
  118. }
  119. function method2(){
  120. methodfollow2();
  121. // 实体对象,就是鼠标点击确定之后的实体对象,并且实体对象的图片引入
  122. cubeGeo = new THREE.SphereGeometry( 50, 10, 10 );
  123. cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x4D662D/*, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" )*/ } );
  124. }
  125. function method3(){
  126. methodfollow3();
  127. // 实体对象,就是鼠标点击确定之后的实体对象,并且实体对象的图片引入
  128. cubeGeo = new THREE.CubeGeometry( 50, 100, 50 );
  129. cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x4D662D, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } );
  130. }
  131. function method4(){
  132. methodfollow4();
  133. // 实体对象,就是鼠标点击确定之后的实体对象,并且实体对象的图片引入
  134. cubeGeo = new THREE.CylinderBufferGeometry( 25,25, 100, 50 ,50);
  135. cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x4D662D, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } );
  136. }
  137. function method5(){
  138. window.open("newwindows.html","_blank","resizable=yes,scrollbars=yes,titlebar=yes,windth=800,height=800");
  139. }
  140.  
  141. function methodfollow1(){
  142. // 这个几何对象是鼠标在移动时候,跟随鼠标显示的几何对象
  143. rollOverGeo = new THREE.BoxGeometry( 50, 50, 50 );//创建一个盒状几何对象
  144. rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
  145. //创建一个色彩为红色的材料,透明度为半透明
  146. rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
  147. //通过mesh方法把颜色应用到几何对象上
  148. scene.add( rollOverMesh );
  149. //最后把该立方体对象添加到场景scene中
  150. }
  151. function methodfollow2(){
  152. // 这个几何对象是鼠标在移动时候,跟随鼠标显示的几何对象
  153. rollOverGeo = new THREE.SphereGeometry( 50, 10, 10 );//创建一个盒状几何对象
  154. rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
  155. //创建一个色彩为红色的材料,透明度为半透明
  156. rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
  157. //通过mesh方法把颜色应用到几何对象上
  158. scene.add( rollOverMesh );
  159. //最后把该立方体对象添加到场景scene中
  160. }
  161. function methodfollow3(){
  162. // 这个几何对象是鼠标在移动时候,跟随鼠标显示的几何对象
  163. rollOverGeo = new THREE.CubeGeometry( 50, 100, 50 );//创建一个盒状几何对象
  164. rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
  165. //创建一个色彩为红色的材料,透明度为半透明
  166. rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
  167. //通过mesh方法把颜色应用到几何对象上
  168. scene.add( rollOverMesh );
  169. //最后把该立方体对象添加到场景scene中
  170. }
  171. function methodfollow4(){
  172. // 这个几何对象是鼠标在移动时候,跟随鼠标显示的几何对象
  173. rollOverGeo = new THREE.CylinderGeometry( 25,25 ,100, 50,50 );//创建一个盒状几何对象
  174. rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
  175. //创建一个色彩为红色的材料,透明度为半透明
  176. rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
  177. //通过mesh方法把颜色应用到几何对象上
  178. scene.add( rollOverMesh );
  179. //最后把该立方体对象添加到场景scene中
  180. }
  181.  
  182. function onWindowResize() {
  183.  
  184. camera.aspect = window.innerWidth / window.innerHeight;
  185. camera.updateProjectionMatrix();
  186.  
  187. renderer.setSize( window.innerWidth, window.innerHeight );
  188.  
  189. }
  190.  
  191. function onDocumentMouseMove( event ) {
  192. event.preventDefault();//取消事件的默认动作
  193. mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );
  194. raycaster.setFromCamera( mouse, camera );
  195. var intersects = raycaster.intersectObjects( objects );
  196. if ( intersects.length > 0 ) {
  197. var intersect = intersects[ 0 ];
  198. rollOverMesh.position.copy( intersect.point ).add( intersect.face.normal );
  199. rollOverMesh.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
  200. }
  201. render();
  202. }
  203. function onDocumentMouseDown( event ) {
  204. event.preventDefault();
  205. mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );
  206. raycaster.setFromCamera( mouse, camera );
  207. var intersects = raycaster.intersectObjects( objects );
  208. if ( intersects.length > 0 ) {
  209. var intersect = intersects[ 0 ];
  210. // delete cube
  211. if ( isShiftDown ) {
  212. if ( intersect.object != plane ) {
  213. scene.remove( intersect.object );
  214. objects.splice( objects.indexOf( intersect.object ), 1 );
  215. }
  216. // create cube
  217. } else {
  218. var voxel = new THREE.Mesh( cubeGeo, cubeMaterial );
  219. voxel.position.copy( intersect.point ).add( intersect.face.normal );
  220. voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
  221. scene.add( voxel );
  222. objects.push( voxel );
  223. }
  224. render();
  225. }
  226. }
  227. function onDocumentKeyDown( event ) {
  228. switch( event.keyCode ) {
  229. case 16: isShiftDown = true; break;
  230. }
  231. }
  232. function onDocumentKeyUp( event ) {
  233. switch ( event.keyCode ) {
  234. case 16: isShiftDown = false; break;
  235. }
  236. }
  237. function render() {
  238.  
  239. renderer.render( scene, camera );
  240.  
  241. }
  242.  
  243. </script>
  244. </body>
  245. </html>

源代码

    2、其实这个小程序没什么多大的难度,主要是娱乐一下,可能有些大神能做出更好的,当然,我要是做的很好,我为什么还在上学呢,哈哈!

    3、这里又一个小小的私心,每次看到博客园的很多大牛,都是粉丝很多很多,我看了看我自己的只有3个,额,我的意思是希望大家相互关注一下,以后有什么好的博客,大家也能及时的看到!嘿嘿,不过这不是打广告,只是我感觉每次有个人关注我之后,我都兴奋了好几个小时,然后我也会关注他。

    4、大家有什么好的建议和意见都可以提出来,我都虚心接受的,我接触的东西肯定没有广大的博友多,希望大家相互照顾!谢谢。看了看时间:2016年6月25日凌晨3:34,从11点多开始写,改了很多地方,怕自己的东西大家看了不喜欢,我会努力的!该睡觉了,10点钟还有课呢,头疼/(ㄒoㄒ)/~~

分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”的更多相关文章

  1. [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so

    0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...

  2. [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so

    0:前言 1:本文主要作为丙方android公司的身份来写 2:作者有不对的地方,请指出,谢谢 [第一篇:android利用jni调用第三方库——编写库libhello.so] [第二篇:androi ...

  3. 利用SpringBoot+Logback手写一个简单的链路追踪

    目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...

  4. 利用生产者消费者模型和MQ模型写一个自己的日志系统-并发设计里一定会用到的手段

    一:前言 写这个程序主要是用来理解生产者消费者模型,以及通过这个Demo来理解Redis的单线程取原子任务是怎么实现的和巩固一下并发相关的知识:这个虽然是个Demo,但是只要稍加改下Appender部 ...

  5. CS184.1X 计算机图形学导论 作业0

    1.框架下载 在网站上下载了VS2012版本的作业0的框架,由于我的电脑上的VS是2017版的,根据提示安装好C++的版本,并框架的解决方案 重定解决方案目标为2017版本. 点击运行,可以出来界面. ...

  6. linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码

    计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针  (stack pointer) ...

  7. 利用JS实现一个简单的二级联动菜单

    前几天在看js的相关内容,所以就简单写了一个二级联动菜单.分享一下. <!DOCTYPE html> <html lang="en"> <head&g ...

  8. 利用matlab写一个简单的拉普拉斯变换提取图像边缘

    可以证明,最简单的各向同性微分算子是拉普拉斯算子.一个二维图像函数 f(x,y) 的拉普拉斯算子定义为 ​ 其中,在 x 方向可近似为 ​ 同理,在 y 方向上可近似为 ​ 于是 我们得到满足以上三个 ...

  9. 转--利用函数模板技术,写一个简单高效的 JSON 查询器

    http://www.cnblogs.com/index-html/archive/2012/07/18/js_select.html http://www.ibm.com/developerwork ...

随机推荐

  1. Innodb行锁源码学习(一)

    Innodb是mysql数据库中目前最流行的存储引擎,innodb相对其它存储引擎一个很大的特点是支持事务,并且支持行粒度的锁.今天我重点跟大家分享下innodb行锁实现的基础知识.由于篇幅比较大,文 ...

  2. Java并发之工具类 ForkJoin 任务分解

    Fork/Join框架的介绍 第一步分割任务.首先我们需要有一个fork类来把大任务分割成子任务,有可能子任务还是很大,所以还需要不停的分割,直到分割出的子任务足够小. 第二步执行任务并合并结果.分割 ...

  3. android 反编译apktool工具

    下载地址:http://pan.baidu.com/s/1bnHANtd 1.将编译的*.apk放在apktool的根目录下:2.双击“解压软件.bat”后,会提示完成:这样就反编译成功以:3.查看反 ...

  4. eclipse 提示错误**cannot be resolved to a type

    这是某个对象不能识别为类型,比如你写了个类,名字叫Hello,如果你调用它的时候不小心写成hello,或者helo,那么就会报这样的错误,很容易改正的,只要你细心一点

  5. PCIe 32GT/s 含义

    如下: Jul 26 03:42:53 kernel: ixgbe 0000:01:00.1: PCI Express bandwidth of 32GT/s available Jul 26 03: ...

  6. TCP连接建立系列 — 服务端接收ACK段(一)

      http://blog.csdn.net/zhangskd/article/details/17923917 分类: Linux TCP/IP Linux Kernel 2014-01-07 09 ...

  7. 多CPU下基于e1000e驱动的数据包以及网卡中断流程分析.doc

    http://wenku.baidu.com/link?url=mMKDH_fKmUXN7L6rANIFHjoHdKCYBLlDrqoYB1daDTEkNFk9Bt9xlJtS_4BKBj6w22WD ...

  8. mysql 分库分表

    分表是分散数据库压力的好方法. 分表,最直白的意思,就是将一个表结构分为多个表,然后,可以再同一个库里,也可以放到不同的库. 当然,首先要知道什么情况下,才需要分表.个人觉得单表记录条数达到百万到千万 ...

  9. ELK日志解决方案安装配置与使用

    官方网站:https://www.elastic.co/products/elasticsearch logstash,elasticsearch,kibana作用如下: logstash:分布在每一 ...

  10. TestNG之注解的生命周期

    有必要介绍一下TestNG注解的生命周期,先看一下官网支持的注解有 @BeforeSuite@AfterSuite@BeforeTest@AfterTest@BeforeGroups@AfterGro ...