commit 081aee5eb625cbd4efbdda476ce5ed2b67aabf57
parent 35b0fc20ed38f25957540280bbbab655cdd428a9
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Thu, 4 Jul 2024 14:28:11 -0300
add first person camera instructions and controls
Diffstat:
M | tp/scene.html | | | 45 | ++++++++++++++++++++++++++++++++++++++++++++- |
M | tp/src/scene.js | | | 82 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
2 files changed, 124 insertions(+), 3 deletions(-)
diff --git a/tp/scene.html b/tp/scene.html
@@ -9,10 +9,53 @@
padding: 0;
margin: 0;
height: 100%;
+
+ #blocker {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0,0,0,0.5);
+ backdrop-filter: blur(5px);
+ }
+
+ #instructions {
+ width: 100%;
+ height: 100%;
+
+ /* display: flex; */
+ display: none;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ padding-top: 0;
+ text-align: center;
+ font-size: 20px;
+ cursor: pointer;
+
+ text-shadow: 1px 1px 2px white;
+ }
+
+ #click-to-play {
+ font-size: 42px;
+ padding: 0em;
+ margin: 0em;
+ }
</style>
</head>
<body>
- <div id="mainContainer"></div>
+ <div id="blocker">
+ <div id="instructions">
+ <p id="click-to-play">
+ Click to play
+ </p>
+ <p>
+ Move: WASD<br/>
+ Jump: SPACE<br/>
+ Look: MOUSE
+ </p>
+ </div>
+ </div>
<script type="module" src="/src/scene.js"></script>
</body>
</html>
diff --git a/tp/src/scene.js b/tp/src/scene.js
@@ -1,6 +1,8 @@
import * as THREE from 'three';
import * as dat from 'dat.gui';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
+import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
+import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
import { vertexShader, fragmentShader } from '/assets/shaders.js';
import { generateTunnelGeometry } from '/src/tunnel.js';
@@ -18,6 +20,8 @@ import { updateTrainCrankPosition } from '/src/train.js';
let scene, camera, renderer, terrainMaterial, terrainGeometry, terrain, time;
let treesForbiddenMapData, treesForbiddenMap, elevationMap, elevationMapData;
+let firstPersonControls, orbitControls;
+
let train, gui;
let cameras = [];
@@ -62,12 +66,51 @@ function onResize() {
function nextCamera() {
const camerasCount = cameras.length;
+ if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
+ firstPersonControls.unlock();
+ blocker.style.display = 'none';
+ instructions.style.display = 'flex';
+ }
+
if(settings.currCameraIndex == (camerasCount - 1)) {
- console.log("Restarting cameras");
settings.currCameraIndex = 0;
} else {
settings.currCameraIndex += 1;
}
+
+ if(cameras[settings.currCameraIndex].name == "firstPersonCamera") {
+ firstPersonControls.unlock();
+ blocker.style.display = 'block';
+ instructions.style.display = 'flex';
+ }
+}
+
+const blocker = document.getElementById( 'blocker' );
+const instructions = document.getElementById( 'instructions' );
+
+function firstPersonCameraHandler(eventName) {
+ // if(cameras[settings.currCameraIndex].name != "firstPersonCamera") {
+ // console.log(cameras[settings.currCameraIndex].name);
+ // return;
+ // }
+
+ // console.log(eventName);
+ switch(eventName) {
+ case 'click':
+ console.log('click');
+ firstPersonControls.lock();
+ break;
+ case 'lock':
+ console.log('lock');
+ instructions.style.display = 'none';
+ blocker.style.display = 'none';
+ break;
+ case 'unlock':
+ console.log('unlock');
+ blocker.style.display = 'block';
+ instructions.style.display = 'flex';
+ break;
+ }
}
function setupThreeJs() {
@@ -89,7 +132,7 @@ function setupThreeJs() {
topView.name = "topView"
cameras.push(topView);
- const controls = new OrbitControls(topView, renderer.domElement);
+ orbitControls = new OrbitControls(topView, renderer.domElement);
const firstPersonCamera = new THREE.PerspectiveCamera(
50, window.innerWidth / window.innerHeight, 0.1, 1000);
@@ -99,6 +142,25 @@ function setupThreeJs() {
firstPersonCamera.name = "firstPersonCamera"
cameras.push(firstPersonCamera);
+ firstPersonControls = new PointerLockControls(firstPersonCamera, document.body);
+
+
+ instructions.addEventListener('click', function() {
+ // console.log(event);
+ firstPersonCameraHandler('click');
+ });
+
+ firstPersonControls.addEventListener('lock', function() {
+ // console.log(event);
+ firstPersonCameraHandler('lock');
+ });
+
+ firstPersonControls.addEventListener('unlock', function() {
+ // console.log(event);
+ firstPersonCameraHandler('unlock');
+ });
+ scene.add(firstPersonControls.getObject());
+
const ambientLight = new THREE.AmbientLight(0xFFFFFF);
scene.add(ambientLight);
@@ -389,6 +451,22 @@ function buildScene() {
function mainLoop() {
let currCamera = cameras[settings.currCameraIndex];
+ switch(currCamera.name) {
+ case "topView":
+ orbitControls.enabled = true;
+ blocker.style.display = 'none';
+ instructions.style.display = 'none';
+ break;
+ case "firstPersonCamera":
+ orbitControls.enabled = false;
+ break;
+ default:
+ orbitControls.enabled = false;
+ blocker.style.display = 'none';
+ instructions.style.display = 'none';
+ break;
+ }
+
requestAnimationFrame(mainLoop);
renderer.render(scene, currCamera);