123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <title>three.js webgl - minimap</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <link type="text/css" rel="stylesheet" href="main.css">
- <style>
- a {
- color: #08f;
- }
- b {
- color: lightgreen;
- }
- #mask {
- position: absolute;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.4);
- }
- #text {
- position: absolute;
- font-size: 30px;
- width: 100%;
- top: 50%;
- text-align: center;
- cursor: pointer;
- }
- </style>
- </head>
- <body>
- <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a><a> - minimap</a><br />
- </div>
- <div id="mask">
- <div id="text">Click to start</div>
- </div>
- <script type="module">
- import * as THREE from '../build/three.module.js';
- import { PointerLockControls } from './jsm/controls/PointerLockControls.js';
- import { GUI } from './jsm/libs/dat.gui.module.js';
- import { Minimap } from './jsm/misc/Minimap.js';
- var camera, scene, renderer, controls;
- var objects = [];
- var raycaster;
- var moveForward = false;
- var moveBackward = false;
- var moveLeft = false;
- var moveRight = false;
- var canJump = false;
- var isPointerLocked = true;
- var prevTime = performance.now();
- var velocity = new THREE.Vector3();
- var direction = new THREE.Vector3();
- var vertex = new THREE.Vector3();
- var color = new THREE.Color();
- var params = {
- viewRange: 300,
- mapSize: 300
- };
- var minimap;
- init();
- animate();
- function init() {
- //
- renderer = new THREE.WebGLRenderer({ antialias: true });
- renderer.setPixelRatio(window.devicePixelRatio);
- renderer.setSize(window.innerWidth, window.innerHeight);
- document.body.appendChild(renderer.domElement);
- camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
- camera.position.y = 10;
- scene = new THREE.Scene();
- scene.background = new THREE.Color(0xffffff);
- scene.fog = new THREE.Fog(0xffffff, 0, 200);
- var light = new THREE.HemisphereLight(0xeeeeff, 0x777788, 0.75);
- light.position.set(0.5, 1, 0.75);
- scene.add(light);
- //camera controls
- controls = new PointerLockControls(camera, renderer.domElement);
- scene.add(controls.getObject());
- var mask = document.getElementById('mask');
- var text = document.getElementById('text');
- mask.addEventListener('click', function () {
- controls.lock();
- }, false);
- controls.addEventListener('lock', function () {
- mask.style.display = 'none';
- });
- controls.addEventListener('unlock', function () {
- mask.style.display = 'block';
- text.innerText = 'Click to continue';
- });
- renderer.domElement.addEventListener('click', function () {
- controls.unlock();
- mask.style.display = 'block';
- }, false);
- var onKeyDown = function (event) {
- if (!controls.isLocked) return;
- switch (event.keyCode) {
- case 38: // up
- case 87: // w
- moveForward = true;
- break;
- case 37: // left
- case 65: // a
- moveLeft = true;
- break;
- case 40: // down
- case 83: // s
- moveBackward = true;
- break;
- case 39: // right
- case 68: // d
- moveRight = true;
- break;
- case 32: // space
- if (canJump === true) velocity.y += 250;
- canJump = false;
- break;
- }
- };
- var onKeyUp = function (event) {
- switch (event.keyCode) {
- case 38: // up
- case 87: // w
- moveForward = false;
- break;
- case 37: // left
- case 65: // a
- moveLeft = false;
- break;
- case 40: // down
- case 83: // s
- moveBackward = false;
- break;
- case 39: // right
- case 68: // d
- moveRight = false;
- break;
- }
- };
- document.addEventListener('keydown', onKeyDown, false);
- document.addEventListener('keyup', onKeyUp, false);
- raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, - 1, 0), 0, 10);
- // ground mesh
- var groundGeometry = new THREE.PlaneBufferGeometry(2000, 2000, 100, 100);
- groundGeometry.rotateX(- Math.PI / 2);
- var groundMaterial = new THREE.MeshBasicMaterial({ color: new THREE.Color(0.2, 0.75, 0.5) });
- var ground = new THREE.Mesh(groundGeometry, groundMaterial);
- scene.add(ground);
- // obstacles
- for (var i = 0; i < 600; i++) {
- var boxGeometry = new THREE.BoxBufferGeometry(20, 80, 20);
- var boxMaterial = new THREE.MeshPhongMaterial({
- specular: new THREE.Color(Math.random(), Math.random(), Math.random()),
- flatShading: true
- });
- boxMaterial.color.setHSL(Math.random() * 0.2 + 0.4, 0.6, Math.random() * 0.3 + 0.75); //Math.random() * 0.2 + 0.5
- var box = new THREE.Mesh(boxGeometry, boxMaterial);
- box.position.x = Math.floor(Math.random() * 40 - 20) * 20;
- box.position.z = Math.floor(Math.random() * 40 - 20) * 20;
- if (box.position.x == 0 && box.position.z == 0) continue;
- scene.add(box);
- objects.push(box);
- }
- // init minimap
- minimap = new Minimap(renderer, scene, camera, {
- viewRange: params.viewRange,
- mapSize: params.mapSize,
- heightOffset: 100
- });
- var gui = new GUI();
- gui.add(params, 'viewRange', 100, 800);
- gui.add(params, 'mapSize', 100, 500);
- gui.open();
- //
- window.addEventListener('resize', function () {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- renderer.setSize(window.innerWidth, window.innerHeight);
- }, false);
- }
- function animate() {
- requestAnimationFrame(animate);
- // first person control
- raycaster.ray.origin.copy(controls.getObject().position);
- raycaster.ray.origin.y -= 10;
- var intersections = raycaster.intersectObjects(objects);
- var onObject = intersections.length > 0;
- var time = performance.now();
- var delta = (time - prevTime) / 1000;
- velocity.x -= velocity.x * 10.0 * delta;
- velocity.z -= velocity.z * 10.0 * delta;
- velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass
- direction.z = Number(moveForward) - Number(moveBackward);
- direction.x = Number(moveRight) - Number(moveLeft);
- direction.normalize(); // this ensures consistent movements in all directions
- if (moveForward || moveBackward) velocity.z -= direction.z * 400.0 * delta;
- if (moveLeft || moveRight) velocity.x -= direction.x * 400.0 * delta;
- if (onObject === true) {
- velocity.y = Math.max(0, velocity.y);
- canJump = true;
- }
- controls.moveRight(- velocity.x * delta);
- controls.moveForward(- velocity.z * delta);
- controls.getObject().position.y += (velocity.y * delta); // new behavior
- if (controls.getObject().position.y < 10) {
- velocity.y = 0;
- controls.getObject().position.y = 10;
- canJump = true;
- }
- prevTime = time;
- // render main scene
- minimap.setMinimapVisibility(false);
- scene.fog.far = 200;
- renderer.render(scene, camera);
- // render minimap
- scene.fog.far = 100000;
- minimap.viewRange = params.viewRange;
- minimap.mapSize = params.mapSize;
- minimap.renderMinimap();
-
- }
- </script>
- </body>
- </html>
|