接上一节,游戏控制首先要解决的就是碰撞检测了

这里用到了学习笔记(三)射线检测的内容了

以鸟为射线原点,向前、上、下分别发射3个射线,射线的长度较短大概为10~30.

根据上一节场景的建设,我把y轴设为前进方向,z轴设为高度~

如果射线返回有结果,那么说明鸟遇到了障碍物。代码如下:

  1. var raycaster1 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 1, 0), 0, 30)
  2. var raycaster2 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, 1), 0, 10)
  3. var raycaster3 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, -1), 0, 10)
  4. //
  5. var intersections1 = raycaster1.intersectObjects(objects);
  6. var intersections2 = raycaster2.intersectObjects(objects);
  7. var intersections3 = raycaster3.intersectObjects(objects);
  8. //如果前方有物体,向前速度为0
  9. if (intersections1.length > 0)
  10. {
  11. velocity.y = 0;
  12. }
  13.  
  14. //如果上方有物体,向上速度为0或为负值
  15. if (intersections2.length > 0 )
  16. {
  17. if (velocity.z > 0)
  18. {
  19. velocity.z = 0;
  20. }
  21.  
  22. }
  23. //如果下方有物体,向下速度为0或为正值
  24. if (intersections3.length > 0) {
  25. if (velocity.z < 0)
  26. {
  27. velocity.z = 0;
  28. }
  29.  
  30. }
  31.  
  32. if (birdmesh.position.z < 10)
  33. {
  34. birdmesh.position.z = 10;
  35. }
  36.  
  37. if (birdmesh.position.z > 575) {
  38. birdmesh.position.z = 575;
  39. }
  40.  
  41. if (velocity.y==0)
  42. {
  43. alert('您已死亡!');
  44. }

其次需要解决的就是飞行前进和重力下降的问题

首先新建一个

  1. var velocity = new THREE.Vector3();

用velocity.x和.y以及.z来表示像3个方向的速度。

y方向为前进方向,给定一个固定值就行,检测到碰撞停止。

x方向不用管,因为x方向没有运动。

z方向为高度方向,要做到鼠标点击飞高一段距离,然后重力下降。

首先鼠标点击给定一个固定的向上的速度,然后速度加速递减(重力效果),代码如下

  1.                     window.addEventListener('mousedown', function (event) {
  2.  
  3.                         velocity.z = 500;
                            mixer.clipAction(clip).setDuration(0.1).play();
                            
                            
                           
                        }, false);
  4.  
  5.                     window.addEventListener('mouseup', function (event) {
                            
                            mixer.clipAction(clip).setDuration(1).play();
  6.  
  7.                     }, false);
  8.  
  9. var delta = clock.getDelta();
  10.  
  11. //这里100就是速度的一个因子,数值越大,重力效果越明显;
  12. velocity.z -= 9.8 * 100 * delta;
  13.  
  14. birdmesh.position.z += velocity.z*delta;
  15. birdmesh.position.y += velocity.y * delta;
  16.  
  17. velocity.y = 200;

另外上面代码仔细观察,你会发现鼠标点击和松开给定的鸟煽动翅膀的速度是不一样的

  1. mixer.clipAction(clip).setDuration(1).play()

这是为了达到点击鼠标有鸟在努力向上飞的视觉效果~。

先写到这。全部源码先贴在这吧,其实上传工程的效果是最好的,但还没整理好。这个练手还没完!

预告后面两节

后1节:飞行类小游戏转置为win10通用UWP应用(我将上传至微软商店,敬请期待!)

后2节:飞行类小游戏转置为手机安卓应用

最后目前全部源码~

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>练手</title>
  5. <meta charset="utf-8">
  6.  
  7. </head>
  8. <body>
  9.  
  10. <script src="build/three.js"></script>
  11. <script src="js/Detector.js"></script>
  12.  
  13. <script src="js/controls/OrbitControls.js"></script>
  14.  
  15. <script>
  16. if (!Detector.webgl) Detector.addGetWebGLMessage();
  17.  
  18. var camera, scene, renderer;
  19.  
  20. var clock = new THREE.Clock();
  21. //var controls;
  22.  
  23. var velocity = new THREE.Vector3();
  24. var birdmesh;
  25. var objects = [];
  26. init();
  27. animate();
  28.  
  29. function init()
  30. {
  31. container = document.createElement( 'div' );
  32. document.body.appendChild( container );
  33. //
  34. camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 100000);
  35. camera.up.set(0, 0, 1);
  36. camera.lookAt(new THREE.Vector3(-1, 1, 0));
  37.  
  38. scene = new THREE.Scene();
  39. //
  40. scene.add( new THREE.HemisphereLight( 0x443333, 0x222233 ) );
  41. var light = new THREE.DirectionalLight( 0xffffff, 1 );
  42. light.position.set( 1, 1, 1 );
  43. scene.add( light );
  44. //------添加内容
  45.  
  46. //---地板,平面
  47. geometry = new THREE.PlaneGeometry(512, 200000);
  48.  
  49. //geometry.rotateX(-Math.PI / 2);
  50.  
  51. var texture = new THREE.TextureLoader().load('img/dd.jpg');
  52. texture.wrapS = THREE.RepeatWrapping;
  53. texture.wrapT = THREE.RepeatWrapping;
  54. texture.repeat.set(8, 800)
  55. material = new THREE.MeshBasicMaterial({ map: texture });
  56.  
  57. //material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
  58. mesh = new THREE.Mesh(geometry, material);
  59. mesh.position.set(0, 0, 0);
  60. scene.add(mesh);
  61. objects.push(mesh);
  62.  
  63. ////箱子1
  64. //geometry = new THREE.BoxGeometry(2, 2, 2);
  65. //material = new THREE.MeshBasicMaterial({color:0x000000});
  66. //mesh = new THREE.Mesh(geometry, material);
  67. //mesh.position.set(0,0,0);
  68. //scene.add(mesh);
  69.  
  70. ////箱子2
  71. //geometry = new THREE.BoxGeometry(2, 2, 2);
  72. //material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
  73. //mesh = new THREE.Mesh(geometry, material);
  74. //mesh.position.set(100, 0, 0);
  75. //scene.add(mesh);
  76.  
  77. ////箱子3
  78. //geometry = new THREE.BoxGeometry(2, 2, 2);
  79. //material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  80. //mesh = new THREE.Mesh(geometry, material);
  81. //mesh.position.set(0, 100, 0);
  82. //scene.add(mesh);
  83.  
  84. ////箱子4
  85. //geometry = new THREE.BoxGeometry(2, 2, 2);
  86. //material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
  87. //mesh = new THREE.Mesh(geometry, material);
  88. //mesh.position.set(0, 0, 100);
  89. //scene.add(mesh);
  90.  
  91. //天空盒
  92. var textureLoader = new THREE.TextureLoader();
  93. var materials = [
  94. new THREE.MeshBasicMaterial({ map: textureLoader.load('img/px.jpg') }), // right
  95. new THREE.MeshBasicMaterial({ map: textureLoader.load('img/nx.jpg') }), // left
  96. new THREE.MeshBasicMaterial({ map: textureLoader.load('img/py.jpg') }), // top
  97. new THREE.MeshBasicMaterial({ map: textureLoader.load('img/ny.jpg') }), // bottom
  98. new THREE.MeshBasicMaterial({ map: textureLoader.load('img/pz.jpg') }), // back
  99. new THREE.MeshBasicMaterial({ map: textureLoader.load('img/nz.jpg') }) // front
  100. ];
  101. mesh = new THREE.Mesh(new THREE.BoxGeometry(100000, 100000, 100000, 7, 7, 7), new THREE.MultiMaterial(materials));
  102. mesh.scale.x = -1;
  103. scene.add(mesh);
  104.  
  105. //连续障碍物
  106. for (var i = 0; i < 50;i++) {
  107. var ht=Math.random() * 450;
  108. geometry = new THREE.BoxGeometry(80, 20, ht);
  109. material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
  110. mesh = new THREE.Mesh(geometry, material);
  111.  
  112. mesh.position.x =0;
  113. mesh.position.y = (i+1) * 500;
  114. mesh.position.z = ht / 2;
  115. scene.add(mesh);
  116.  
  117. objects.push(mesh);
  118.  
  119. geometry = new THREE.BoxGeometry(80, 20, 450-ht);
  120. mesh = new THREE.Mesh(geometry, material);
  121. mesh.position.x = 0;
  122. mesh.position.y = (i + 1) * 500;
  123. mesh.position.z = ht + 140 + (450 - ht) / 2;
  124. scene.add(mesh);
  125.  
  126. objects.push(mesh);
  127.  
  128. }
  129.  
  130. //鸟
  131. var loader = new THREE.JSONLoader();
  132.  
  133. loader.load( "models/animated/flamingo.js", function( geometry ) {
  134. geometry.computeVertexNormals();
  135. geometry.computeMorphNormals();
  136. var material = new THREE.MeshPhongMaterial( {
  137. color: 0xffffff,
  138. morphTargets: true,
  139. morphNormals: true,
  140. vertexColors: THREE.FaceColors,
  141. shading: THREE.SmoothShading
  142. } );
  143. birdmesh = new THREE.Mesh( geometry, material );
  144. birdmesh.position.x = 0;
  145. birdmesh.position.y = 0;
  146. birdmesh.position.z = 200;
  147. birdmesh.scale.set(0.2, 0.2, 0.2);
  148. birdmesh.rotateX(-Math.PI / 2);
  149. birdmesh.rotateZ(Math.PI);
  150. scene.add(birdmesh);
  151. mixer = new THREE.AnimationMixer(birdmesh);
  152.  
  153. var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('bd', geometry.morphTargets, 30);
  154. mixer.clipAction(clip).setDuration(1).play();
  155.  
  156. window.addEventListener('mousedown', function (event) {
  157.  
  158. velocity.z = 500;
  159. mixer.clipAction(clip).setDuration(0.1).play();
  160.  
  161. }, false);
  162.  
  163. window.addEventListener('mouseup', function (event) {
  164.  
  165. mixer.clipAction(clip).setDuration(1).play();
  166.  
  167. }, false);
  168.  
  169. } );
  170.  
  171. renderer = new THREE.WebGLRenderer({ antialias: true });
  172. renderer.setPixelRatio(window.devicePixelRatio);
  173. renderer.setSize(window.innerWidth, window.innerHeight);
  174. container.appendChild( renderer.domElement );
  175.  
  176. //控制
  177.  
  178. //var controls = new THREE.OrbitControls(camera, renderer.domElement);
  179. //controls.addEventListener('change', render);
  180. //controls.target.set(0, 0, 0);
  181. //controls.update();
  182.  
  183. //
  184. window.addEventListener('resize', function onWindowResize(event) {
  185. renderer.setSize(window.innerWidth, window.innerHeight);
  186. camera.aspect = 0.5 * window.innerWidth / window.innerHeight;
  187. camera.updateProjectionMatrix();
  188. }, false);
  189.  
  190. }
  191.  
  192. //
  193. function animate() {
  194.  
  195. requestAnimationFrame( animate );
  196. render();
  197.  
  198. }
  199.  
  200. function render() {
  201.  
  202. var delta = clock.getDelta();
  203.  
  204. //这里100就是速度的一个因子,数值越大,重力效果越明显,等效于velocity.y =(velocity.y*0.01- 9.8 * delta)*100;
  205. velocity.z -= 9.8 * 100 * delta;
  206.  
  207. birdmesh.position.z += velocity.z*delta;
  208. birdmesh.position.y += velocity.y * delta;
  209.  
  210. velocity.y = 200;
  211.  
  212. var raycaster1 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 1, 0), 0, 30)
  213. var raycaster2 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, 1), 0, 10)
  214. var raycaster3 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, -1), 0, 10)
  215. //
  216. var intersections1 = raycaster1.intersectObjects(objects);
  217. var intersections2 = raycaster2.intersectObjects(objects);
  218. var intersections3 = raycaster3.intersectObjects(objects);
  219. //是否检测到
  220.  
  221. if (intersections1.length > 0)
  222. {
  223. velocity.y = 0;
  224. }
  225.  
  226. if (intersections2.length > 0 )
  227. {
  228. if (velocity.z > 0)
  229. {
  230. velocity.z = 0;
  231. }
  232.  
  233. }
  234.  
  235. if (intersections3.length > 0) {
  236. if (velocity.z < 0)
  237. {
  238. velocity.z = 0;
  239. }
  240.  
  241. }
  242.  
  243. if (birdmesh.position.z < 10)
  244. {
  245. birdmesh.position.z = 10;
  246. }
  247.  
  248. if (birdmesh.position.z > 575) {
  249. birdmesh.position.z = 575;
  250. }
  251.  
  252. if (velocity.y==0)
  253. {
  254. alert('您已死亡!');
  255. }
  256.  
  257. mixer.update(delta);
  258.  
  259. camera.position.set(birdmesh.position.x+100, birdmesh.position.y - 50, birdmesh.position.z);
  260.  
  261. renderer.clear();
  262. renderer.render( scene, camera );
  263. }
  264. </script>
  265.  
  266. </body>
  267. </html>

WEBGL学习笔记(七):实践练手1-飞行类小游戏之游戏控制的更多相关文章

  1. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  2. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  3. java jvm学习笔记七(jar包的代码认证和签名)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...

  4. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  6. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

  8. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  9. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

随机推荐

  1. Tinyxml2学习

    转自http://www.360doc.com/content/13/1223/16/3684846_339528825.shtml,尊重原文 什么是XML? XML全称EXtensible Mark ...

  2. 解决Cannot change version of project facet Dynamic Web M 3.0

    解决Cannot change version of project facet Dynamic Web M 3.0 dynamic web module 版本之间的区别: Servlet 3.0 D ...

  3. 【sqli-labs】 less26 GET- Error based -All you SPACES and COMMENTS belong to us(GET型基于错误的去除了空格和注释的注入)

    看了下源码 所有的注释形式和反斜线,and,or都被了过滤掉了 单引号没有过滤 空格也被过滤了 http://localhost/sqli-labs-master/Less-26/?id=1' htt ...

  4. Pjax无刷新跳转页面实现,支持超链接与表单提交

    什么是pjax? 当你点击一个站内的链接的时候,不是做页面跳转,而是只是站内页面刷新.这样的用户体验,比起整个页面都闪一下来说, 好很多. 其中有一个很重要的组成部分, 这些网站的ajax刷新是支持浏 ...

  5. html 复杂表格

    123456789 123456789 0000000000 日期 123456789 1234560000000789 ----------- ----------- ----------- --- ...

  6. class path resource [processes/] cannot be resolved to URL because it does not exist

    springboot整合activiti时报以下错误,原因是项目启动时检查流程文件 nested exception is java.io.FileNotFoundException: class p ...

  7. wx小程序开发 1:小程序代码构成

    官网学习地址:https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/introduction.html 1: 2:待续.. ...

  8. 切换原生appium里面H5页面

    #coding = utf-8from appium import webdriverimport time'''1.手机类型2.版本3.手机的唯一标识 deviceName4.app 包名appPa ...

  9. [kernel]----理解kswapd的低水位min_free_kbytes

    1. min_free_kbytes 先看官方解释: This is used to force the Linux VM to keep a minimum number of kilobytes ...

  10. C++判断质数

    using namespace std; bool isPrimeNum(int n) { if(n<2) return true; for(int i=2;i*i<=n;i++) { i ...