webgl_camera_minimap.html 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>three.js webgl - minimap</title>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  7. <link type="text/css" rel="stylesheet" href="main.css">
  8. <style>
  9. a {
  10. color: #08f;
  11. }
  12. b {
  13. color: lightgreen;
  14. }
  15. #mask {
  16. position: absolute;
  17. width: 100%;
  18. height: 100%;
  19. background-color: rgba(0, 0, 0, 0.4);
  20. }
  21. #text {
  22. position: absolute;
  23. font-size: 30px;
  24. width: 100%;
  25. top: 50%;
  26. text-align: center;
  27. cursor: pointer;
  28. }
  29. </style>
  30. </head>
  31. <body>
  32. <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a><a> - minimap</a><br />
  33. </div>
  34. <div id="mask">
  35. <div id="text">Click to start</div>
  36. </div>
  37. <script type="module">
  38. import * as THREE from '../build/three.module.js';
  39. import { PointerLockControls } from './jsm/controls/PointerLockControls.js';
  40. import { GUI } from './jsm/libs/dat.gui.module.js';
  41. import { Minimap } from './jsm/misc/Minimap.js';
  42. var camera, scene, renderer, controls;
  43. var objects = [];
  44. var raycaster;
  45. var moveForward = false;
  46. var moveBackward = false;
  47. var moveLeft = false;
  48. var moveRight = false;
  49. var canJump = false;
  50. var isPointerLocked = true;
  51. var prevTime = performance.now();
  52. var velocity = new THREE.Vector3();
  53. var direction = new THREE.Vector3();
  54. var vertex = new THREE.Vector3();
  55. var color = new THREE.Color();
  56. var params = {
  57. viewRange: 300,
  58. mapSize: 300
  59. };
  60. var minimap;
  61. init();
  62. animate();
  63. function init() {
  64. //
  65. renderer = new THREE.WebGLRenderer({ antialias: true });
  66. renderer.setPixelRatio(window.devicePixelRatio);
  67. renderer.setSize(window.innerWidth, window.innerHeight);
  68. document.body.appendChild(renderer.domElement);
  69. camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
  70. camera.position.y = 10;
  71. scene = new THREE.Scene();
  72. scene.background = new THREE.Color(0xffffff);
  73. scene.fog = new THREE.Fog(0xffffff, 0, 200);
  74. var light = new THREE.HemisphereLight(0xeeeeff, 0x777788, 0.75);
  75. light.position.set(0.5, 1, 0.75);
  76. scene.add(light);
  77. //camera controls
  78. controls = new PointerLockControls(camera, renderer.domElement);
  79. scene.add(controls.getObject());
  80. var mask = document.getElementById('mask');
  81. var text = document.getElementById('text');
  82. mask.addEventListener('click', function () {
  83. controls.lock();
  84. }, false);
  85. controls.addEventListener('lock', function () {
  86. mask.style.display = 'none';
  87. });
  88. controls.addEventListener('unlock', function () {
  89. mask.style.display = 'block';
  90. text.innerText = 'Click to continue';
  91. });
  92. renderer.domElement.addEventListener('click', function () {
  93. controls.unlock();
  94. mask.style.display = 'block';
  95. }, false);
  96. var onKeyDown = function (event) {
  97. if (!controls.isLocked) return;
  98. switch (event.keyCode) {
  99. case 38: // up
  100. case 87: // w
  101. moveForward = true;
  102. break;
  103. case 37: // left
  104. case 65: // a
  105. moveLeft = true;
  106. break;
  107. case 40: // down
  108. case 83: // s
  109. moveBackward = true;
  110. break;
  111. case 39: // right
  112. case 68: // d
  113. moveRight = true;
  114. break;
  115. case 32: // space
  116. if (canJump === true) velocity.y += 250;
  117. canJump = false;
  118. break;
  119. }
  120. };
  121. var onKeyUp = function (event) {
  122. switch (event.keyCode) {
  123. case 38: // up
  124. case 87: // w
  125. moveForward = false;
  126. break;
  127. case 37: // left
  128. case 65: // a
  129. moveLeft = false;
  130. break;
  131. case 40: // down
  132. case 83: // s
  133. moveBackward = false;
  134. break;
  135. case 39: // right
  136. case 68: // d
  137. moveRight = false;
  138. break;
  139. }
  140. };
  141. document.addEventListener('keydown', onKeyDown, false);
  142. document.addEventListener('keyup', onKeyUp, false);
  143. raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, - 1, 0), 0, 10);
  144. // ground mesh
  145. var groundGeometry = new THREE.PlaneBufferGeometry(2000, 2000, 100, 100);
  146. groundGeometry.rotateX(- Math.PI / 2);
  147. var groundMaterial = new THREE.MeshBasicMaterial({ color: new THREE.Color(0.2, 0.75, 0.5) });
  148. var ground = new THREE.Mesh(groundGeometry, groundMaterial);
  149. scene.add(ground);
  150. // obstacles
  151. for (var i = 0; i < 600; i++) {
  152. var boxGeometry = new THREE.BoxBufferGeometry(20, 80, 20);
  153. var boxMaterial = new THREE.MeshPhongMaterial({
  154. specular: new THREE.Color(Math.random(), Math.random(), Math.random()),
  155. flatShading: true
  156. });
  157. boxMaterial.color.setHSL(Math.random() * 0.2 + 0.4, 0.6, Math.random() * 0.3 + 0.75); //Math.random() * 0.2 + 0.5
  158. var box = new THREE.Mesh(boxGeometry, boxMaterial);
  159. box.position.x = Math.floor(Math.random() * 40 - 20) * 20;
  160. box.position.z = Math.floor(Math.random() * 40 - 20) * 20;
  161. if (box.position.x == 0 && box.position.z == 0) continue;
  162. scene.add(box);
  163. objects.push(box);
  164. }
  165. // init minimap
  166. minimap = new Minimap(renderer, scene, camera, {
  167. viewRange: params.viewRange,
  168. mapSize: params.mapSize,
  169. heightOffset: 100
  170. });
  171. var gui = new GUI();
  172. gui.add(params, 'viewRange', 100, 800);
  173. gui.add(params, 'mapSize', 100, 500);
  174. gui.open();
  175. //
  176. window.addEventListener('resize', function () {
  177. camera.aspect = window.innerWidth / window.innerHeight;
  178. camera.updateProjectionMatrix();
  179. renderer.setSize(window.innerWidth, window.innerHeight);
  180. }, false);
  181. }
  182. function animate() {
  183. requestAnimationFrame(animate);
  184. // first person control
  185. raycaster.ray.origin.copy(controls.getObject().position);
  186. raycaster.ray.origin.y -= 10;
  187. var intersections = raycaster.intersectObjects(objects);
  188. var onObject = intersections.length > 0;
  189. var time = performance.now();
  190. var delta = (time - prevTime) / 1000;
  191. velocity.x -= velocity.x * 10.0 * delta;
  192. velocity.z -= velocity.z * 10.0 * delta;
  193. velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass
  194. direction.z = Number(moveForward) - Number(moveBackward);
  195. direction.x = Number(moveRight) - Number(moveLeft);
  196. direction.normalize(); // this ensures consistent movements in all directions
  197. if (moveForward || moveBackward) velocity.z -= direction.z * 400.0 * delta;
  198. if (moveLeft || moveRight) velocity.x -= direction.x * 400.0 * delta;
  199. if (onObject === true) {
  200. velocity.y = Math.max(0, velocity.y);
  201. canJump = true;
  202. }
  203. controls.moveRight(- velocity.x * delta);
  204. controls.moveForward(- velocity.z * delta);
  205. controls.getObject().position.y += (velocity.y * delta); // new behavior
  206. if (controls.getObject().position.y < 10) {
  207. velocity.y = 0;
  208. controls.getObject().position.y = 10;
  209. canJump = true;
  210. }
  211. prevTime = time;
  212. // render main scene
  213. minimap.setMinimapVisibility(false);
  214. scene.fog.far = 200;
  215. renderer.render(scene, camera);
  216. // render minimap
  217. scene.fog.far = 100000;
  218. minimap.viewRange = params.viewRange;
  219. minimap.mapSize = params.mapSize;
  220. minimap.renderMinimap();
  221. }
  222. </script>
  223. </body>
  224. </html>