admin管理员组文章数量:1321074
I'm pletely new to three.js and 3D. I'm trying to make a really simple first person shooter. I found heaps of examples but they all look really plicated. I want to understand the code before I use it. What I am having trouble with is the camera rotation. Everything else is fine. My approach doesn't quite work. It seems to be rotating on the z axis even though I'm setting that to 0. Here's all my code (125 lines)
var width = window.innerWidth, height = window.innerHeight,
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000),
renderer = new THREE.WebGLRenderer(),
mouse = {
x: 0,
y: 0,
movedThisFrame: false
};
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var floorgeometry = new THREE.BoxGeometry(100,0.1,100);
var floormaterial = new THREE.MeshBasicMaterial({
color: 0xff0000
});
var floor = new THREE.Mesh(floorgeometry, floormaterial);
floor.position.y = -1;
scene.add(floor);
var keys = {
w: false,
a: false,
s: false,
d: false
};
camera.position.z = 5;
function radDeg(radians) {
return radians * 180 / Math.PI;
}
function degRad(degrees) {
return degrees * Math.PI / 180;
}
function rotateCam() {
if (!mouse.movedThisFrame) {
mouse.x = 0;
mouse.y = 0;
}
/*
What am I doing wrong here?
*/
camera.rotation.x -= mouse.y * 0.001;
camera.rotation.y -= mouse.x * 0.001;
camera.rotation.z = 0;
mouse.movedThisFrame = false;
}
function moveCam() {
var rotation = camera.rotation.y % (Math.PI * 2), motion = [0,0];
if (keys.w) {
motion[0] += 0.1 * Math.cos(rotation);
motion[1] += 0.1 * Math.sin(rotation);
}
if (keys.a) {
motion[0] += 0.1 * Math.cos(rotation + degRad(90));
motion[1] += 0.1 * Math.sin(rotation + degRad(90));
}
if (keys.s) {
motion[0] += 0.1 * Math.cos(rotation - degRad(180));
motion[1] += 0.1 * Math.sin(rotation - degRad(180));
}
if (keys.d) {
motion[0] += 0.1 * Math.cos(rotation - degRad(90));
motion[1] += 0.1 * Math.sin(rotation - degRad(90));
}
camera.position.z -= motion[0];
camera.position.x -= motion[1];
}
window.onload = function() {
renderer.domElement.onclick = function() {
console.log('requested pointer lock');
renderer.domElement.requestPointerLock();
};
renderer.domElement.onmousemove = function(e) {
if (!mouse.movedThisFrame) {
mouse.x = e.movementX;
mouse.y = e.movementY;
mouse.movedThisFrame = true;
}
};
document.onkeydown = function(e) {
var char = String.fromCharCode(e.keyCode);
if (char == 'W')
keys.w = true;
else if (char == 'A')
keys.a = true;
else if (char == 'S')
keys.s = true;
else if (char == 'D')
keys.d = true;
};
document.onkeyup = function(e) {
var char = String.fromCharCode(e.keyCode);
if (char == 'W')
keys.w = false;
else if (char == 'A')
keys.a = false;
else if (char == 'S')
keys.s = false;
else if (char == 'D')
keys.d = false;
};
function animate() {
requestAnimationFrame(animate);
rotateCam();
moveCam();
renderer.render(scene, camera);
}
animate();
};
The problem is in the rotateCam
function. It doesn't quite work and I don't really know why.
I also tried using the code on this question but it didn't work.
I'm pletely new to three.js and 3D. I'm trying to make a really simple first person shooter. I found heaps of examples but they all look really plicated. I want to understand the code before I use it. What I am having trouble with is the camera rotation. Everything else is fine. My approach doesn't quite work. It seems to be rotating on the z axis even though I'm setting that to 0. Here's all my code (125 lines)
var width = window.innerWidth, height = window.innerHeight,
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000),
renderer = new THREE.WebGLRenderer(),
mouse = {
x: 0,
y: 0,
movedThisFrame: false
};
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var floorgeometry = new THREE.BoxGeometry(100,0.1,100);
var floormaterial = new THREE.MeshBasicMaterial({
color: 0xff0000
});
var floor = new THREE.Mesh(floorgeometry, floormaterial);
floor.position.y = -1;
scene.add(floor);
var keys = {
w: false,
a: false,
s: false,
d: false
};
camera.position.z = 5;
function radDeg(radians) {
return radians * 180 / Math.PI;
}
function degRad(degrees) {
return degrees * Math.PI / 180;
}
function rotateCam() {
if (!mouse.movedThisFrame) {
mouse.x = 0;
mouse.y = 0;
}
/*
What am I doing wrong here?
*/
camera.rotation.x -= mouse.y * 0.001;
camera.rotation.y -= mouse.x * 0.001;
camera.rotation.z = 0;
mouse.movedThisFrame = false;
}
function moveCam() {
var rotation = camera.rotation.y % (Math.PI * 2), motion = [0,0];
if (keys.w) {
motion[0] += 0.1 * Math.cos(rotation);
motion[1] += 0.1 * Math.sin(rotation);
}
if (keys.a) {
motion[0] += 0.1 * Math.cos(rotation + degRad(90));
motion[1] += 0.1 * Math.sin(rotation + degRad(90));
}
if (keys.s) {
motion[0] += 0.1 * Math.cos(rotation - degRad(180));
motion[1] += 0.1 * Math.sin(rotation - degRad(180));
}
if (keys.d) {
motion[0] += 0.1 * Math.cos(rotation - degRad(90));
motion[1] += 0.1 * Math.sin(rotation - degRad(90));
}
camera.position.z -= motion[0];
camera.position.x -= motion[1];
}
window.onload = function() {
renderer.domElement.onclick = function() {
console.log('requested pointer lock');
renderer.domElement.requestPointerLock();
};
renderer.domElement.onmousemove = function(e) {
if (!mouse.movedThisFrame) {
mouse.x = e.movementX;
mouse.y = e.movementY;
mouse.movedThisFrame = true;
}
};
document.onkeydown = function(e) {
var char = String.fromCharCode(e.keyCode);
if (char == 'W')
keys.w = true;
else if (char == 'A')
keys.a = true;
else if (char == 'S')
keys.s = true;
else if (char == 'D')
keys.d = true;
};
document.onkeyup = function(e) {
var char = String.fromCharCode(e.keyCode);
if (char == 'W')
keys.w = false;
else if (char == 'A')
keys.a = false;
else if (char == 'S')
keys.s = false;
else if (char == 'D')
keys.d = false;
};
function animate() {
requestAnimationFrame(animate);
rotateCam();
moveCam();
renderer.render(scene, camera);
}
animate();
};
The problem is in the rotateCam
function. It doesn't quite work and I don't really know why.
I also tried using the code on this question but it didn't work.
Share Improve this question edited May 23, 2017 at 11:59 CommunityBot 11 silver badge asked Apr 10, 2016 at 1:27 Sneaky TurtleSneaky Turtle 3012 silver badges11 bronze badges 1- After some thinking a doodling I now understand the problem. Basically, we need to calculate the X and z angles based of the y angle. But I have no idea how to do that. Someone please help! – Sneaky Turtle Commented Apr 10, 2016 at 1:39
3 Answers
Reset to default 5First person controls are more plicated than you may think. Even if you figure out your angle math, when the pointer is not locked, the mouse hits the window edge and turning stops.
I suggest you start with the pointer lock example (http://threejs/examples/#misc_controls_pointerlock) which is an example of first person controls for 3js.
Here's my Three.js first person shooter demo solution. It's using the PointerLockControls class.
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js Examples - First Person Shooter Game Starter</title>
<style>
@font-face {
font-family: 'Robus-BWqOd';
src: url('https://www.shanebrumback./fonts/Robus-BWqOd.otf') format('opentype');
}
body {
margin: 0;
}
canvas {
display: block;
}
#blocker {
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
#instructions {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
}
#crosshair {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
display: none; /* Hide the crosshair by default */
}
#playButton {
font-family: 'Robus-BWqOd';
font-size: 5vw;
color: white;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.75);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
white-space: nowrap;
}
p {
font-family: Arial;
font-size: medium;
text-align: center;
}
@media (max-width: 900px) {
/* Styles for mobile devices with a maximum width of 767px */
#playButton {
font-family: 'Robus-BWqOd';
font-size: 15vw; /* Adjust the font size as per your preference */
}
p {
font-size: 4vw;
}
}
</style>
</head>
<body>
<div id="blocker">
<div id="instructions">
<div id="playButton">
Play Now
<p>
ESC - Menu
<br />
WASF ARROWS - Move
<br />
LEFT MOUSE - Fire
<br />
SPACEBAR - Fire
<br />
M - Play / Pause Music
</p>
</div>
</div>
</div>
<img id="crosshair" src="https://www.shanebrumback./images/reticle.png" alt="Crosshair">
<script src="https://cdn.jsdelivr/npm/three@latest/build/three.min.js"></script>
<script src="https://cdn.jsdelivr/npm/three@latest/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdn.jsdelivr/npm/three@latest/examples/js/controls/PointerLockControls.js"></script>
<script type="module">
// Set up the scene
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(9, 0.3, 3); // Set camera position 0.1 units above the grid
// Create the renderer
var renderer = new THREE.WebGLRenderer({ alpha: true, depth: true });
// Configure renderer settings
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.setClearColor(0x000000, 1); // Set background color to black
renderer.domElement.style.position = 'fixed';
renderer.domElement.id = 'renderer';
renderer.domElement.style.zIndex = '-1';
renderer.domElement.style.left = '0';
renderer.domElement.style.top = '0';
document.body.appendChild(renderer.domElement);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var particles = [];
var triangles = [];
let cubes = []
var hasCubeMoved = false; // Flag to track if the cube has already been moved
// Gravity effect variables
var gravity = new THREE.Vector3(0, -0.01, 0); // Adjust the gravity strength as needed
var maxGravityDistance = 2; // Adjust the maximum distance affected by gravity as needed
// Add PointerLockControls
var controls = new THREE.PointerLockControls(camera, document.body);
// Create a grid
var gridHelper = new THREE.GridHelper(20, 20);
// Set the color of the grid lines to white
gridHelper.material.color.set(0xffffff);
scene.add(gridHelper);
// Create a plane geometry with the same size as the grid
var planeGeometry = new THREE.PlaneGeometry(20, 20);
// Create a blue material
var blueMaterial = new THREE.MeshBasicMaterial({
color: 0x0000ff,
side: THREE.DoubleSide
});
// Create a plane mesh with the geometry and material
var planeMesh = new THREE.Mesh(planeGeometry, blueMaterial);
// Rotate the grid by 90 degrees
planeMesh.rotation.x = Math.PI / 2;
// Set the position of the plane to align with the grid
planeMesh.position.copy(gridHelper.position);
//scene.add(planeMesh);
// Create a cube
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
for (var i = 0; i < 5; i++) {
var cube = new THREE.Mesh(geometry, material);
cube.position.set(0, 0.5, 0); // Set cube position 0.5 units above the grid
scene.add(cube);
cubes.push(cube);
}
// Set camera to face cube position
camera.lookAt(cube.position)
// Set up pointer lock controls
var blocker = document.getElementById('blocker');
var instructions = document.getElementById('instructions');
var playButton = document.getElementById('playButton');
playButton.addEventListener('click', function () {
controls.lock();
});
controls.addEventListener('lock', function () {
instructions.style.display = 'none';
blocker.style.display = 'none';
document.getElementById('crosshair').style.display = 'block'; // Show the crosshair when screen is locked
});
controls.addEventListener('unlock', function () {
blocker.style.display = 'block';
instructions.style.display = '';
document.getElementById('crosshair').style.display = 'none'; // Hide the crosshair when screen is unlocked
});
scene.add(controls.getObject());
// Keyboard controls
var moveForward = false;
var moveBackward = false;
var moveLeft = false;
var moveRight = false;
var onKeyDown = function (event) {
switch (event.keyCode) {
case 38: // up arrow
case 87: // W key
moveForward = true;
break;
case 37: // left arrow
case 65: // A key
moveLeft = true;
break;
case 40: // down arrow
case 83: // S key
moveBackward = true;
break;
case 39: // right arrow
case 68: // D key
moveRight = true;
break;
}
};
var onKeyUp = function (event) {
switch (event.keyCode) {
case 38: // up arrow
case 87: // W key
moveForward = false;
break;
case 37: // left arrow
case 65: // A key
moveLeft = false;
break;
case 40: // down arrow
case 83: // S key
moveBackward = false;
break;
case 39: // right arrow
case 68: // D key
moveRight = false;
break;
}
};
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);
// Check collision with the grid
function checkCollision(position) {
var gridSize = 20;
var halfGridSize = gridSize / 2;
var margin = 0.1;
if (
position.x < -halfGridSize + margin ||
position.x > halfGridSize - margin ||
position.z < -halfGridSize + margin ||
position.z > halfGridSize - margin
) {
return true; // Collision detected
}
return false; // No collision
}
// Render loop
function animate() {
requestAnimationFrame(animate);
updateParticles();
checkParticleCollision();
if (controls.isLocked) {
var delta = 0.03;
if (moveForward) {
controls.moveForward(delta);
if (checkCollision(controls.getObject().position)) {
controls.moveForward(-delta); // Move back to the previous position
}
}
if (moveBackward) {
controls.moveForward(-delta);
if (checkCollision(controls.getObject().position)) {
controls.moveForward(delta); // Move back to the previous position
}
}
if (moveLeft) {
controls.moveRight(-delta);
if (checkCollision(controls.getObject().position)) {
controls.moveRight(delta); // Move back to the previous position
}
}
if (moveRight) {
controls.moveRight(delta);
if (checkCollision(controls.getObject().position)) {
controls.moveRight(-delta); // Move back to the previous position
}
}
}
updateTriangles()
renderer.render(scene, camera);
}
animate();
function removeParticle(particle) {
scene.remove(particle);
particles.splice(particles.indexOf(particle), 1);
}
function createParticle() {
playLaserSound();
var geometry = new THREE.SphereGeometry(0.05, 16, 16);
var material = new THREE.MeshBasicMaterial({ color: 0xADD8E6 });
var particle = new THREE.Mesh(geometry, material);
particle.position.copy(camera.position);
particle.initialDirection = camera.getWorldDirection(new THREE.Vector3());
particle.velocity = particle.initialDirection.clone().multiplyScalar(0.25);
scene.add(particle);
particles.push(particle);
}
function updateParticles() {
var distanceThreshold = 20;
for (var i = particles.length - 1; i >= 0; i--) {
var particle = particles[i];
particle.position.add(particle.velocity);
var distance = particle.position.distanceTo(camera.position);
if (distance > distanceThreshold) {
removeParticle(particle);
}
}
}
function onMouseDown(event) {
event.preventDefault();
if (controls.isLocked) {
// Particle creation is allowed only when controls are locked
if (event.button === 0) {
createParticle();
}
}
}
function onMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
}
// Mouse click event listener
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove, false);
// Declare a variable to count collided particles
var collidedParticles = 0;
var hasCubeMoved = false; // Flag to track if the cube has already been moved
// Check collision between particles and cubes
function checkParticleCollision() {
for (var j = 0; j < cubes.length; j++) {
var cube = cubes[j];
var isColliding = false;
if (cube.visible) {
for (var i = 0; i < particles.length; i++) {
var particle = particles[i];
var particlePosition = particle.position;
var particleEdge = particlePosition
.clone()
.add(particle.velocity.clone().normalize().multiplyScalar(0.1));
raycaster.set(particlePosition, particleEdge.sub(particlePosition).normalize());
var intersects = raycaster.intersectObject(cube);
if (intersects.length === 1) {
// Particle collided with the cube
isColliding = true;
break;
}
}
}
// Set cube color and visibility based on collision status
if (isColliding) {
// Cube is red during collision
cube.material.color.set(0xff0000);
explosion(cube);
moveCubeRandomly(cube);
hasCubeMoved = false; // Reset the flag when the cube is hidden
} else {
// Cube is green when there is no collision
cube.material.color.set(0x00ff00);
// Check if all particles have been removed and the cube has not moved
if (collidedParticles === particles.length && !hasCubeMoved) {
collidedParticles = 0; // Reset the collided particles counter
hasCubeMoved = true; // Set the flag to indicate that the cube has been moved
}
}
}
}
// Move the cube to a random location on the grid
function moveCubeRandomly(cube) {
var gridSize = 20; // Adjust the grid size as desired
var randomX = Math.floor(Math.random() * gridSize) - gridSize / 2;
var randomZ = Math.floor(Math.random() * gridSize) - gridSize / 2;
cube.position.x = randomX;
cube.position.z = randomZ;
}
// Create an explosion of small triangles
function explosion(cube) {
playExplosionSound();
var explosionCount = 50;
for (var i = 0; i < explosionCount; i++) {
var triangle = createTriangle(cube);
scene.add(triangle);
triangles.push(triangle); // Add the triangle to the triangles array
triangle.userData = {
direction: new THREE.Vector3(
Math.random() * 2 - 1,
Math.random() * 2 - 1,
Math.random() * 2 - 1
).normalize(),
speed: Math.random() * 0.05 + 0.01, // Random speed
rotationAxis: new THREE.Vector3(
Math.random(),
Math.random(),
Math.random()
).normalize(),
rotationSpeed: Math.random() * 0.1 + 0.005, // Random rotation speed
distance: 0, // Distance traveled by the triangle
remove: false, // Flag to mark if the triangle should be removed
parentCube: cube, // Reference to the collided cube
};
}
}
// Create a small triangle
function createTriangle(cube) {
var geometry = new THREE.BufferGeometry();
var vertices = new Float32Array([
-0.1, 0, 0,
0.1, 0, 0,
0, 0.1, 0
]);
var indices = new Uint16Array([0, 1, 2]);
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
var material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
var triangle = new THREE.Mesh(geometry, material);
// Set initial position at the center of the collided cube
triangle.position.copy(cube.position);
// Set the rotation to face the camera
triangle.lookAt(camera.position);
// Set random scale
var scale = Math.random() * 1 + 0.5; // Adjust the scale range as desired
triangle.scale.set(scale, scale, scale);
return triangle;
}
// Update the triangles' positions, rotations, and remove them if necessary
function updateTriangles() {
for (var i = 0; i < triangles.length; i++) {
var triangle = triangles[i];
var userData = triangle.userData;
// Move the triangle in its direction at a random speed
var speed = userData.speed;
triangle.position.add(userData.direction.clone().multiplyScalar(speed));
// Rotate the triangle around its rotation axis at a random speed
var rotationSpeed = userData.rotationSpeed;
triangle.rotateOnWorldAxis(userData.rotationAxis, rotationSpeed);
// Update the distance traveled by the triangle
userData.distance += speed;
// If the triangle has traveled a certain distance, mark it for removal
if (userData.distance >= 2) {
userData.remove = true;
}
}
// Remove triangles that are marked for removal
for (var i = triangles.length - 1; i >= 0; i--) {
if (triangles[i].userData.remove) {
scene.remove(triangles[i]);
triangles.splice(i, 1);
}
}
// Resize renderer when window size changes
window.addEventListener('resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
}
// Create an AudioContext
var audioContext = null;
var musicBuffer = null;
var laserSoundBuffer = null;
var explosionSoundBuffer = null;
var isMusicPlaying = false;
var musicSource = null;
// Function to load audio files
function loadAudioFile(url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function () {
audioContext.decodeAudioData(request.response, function (buffer) {
callback(buffer);
});
};
request.send();
}
// Function to play the music
function playMusic() {
if (!audioContext) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
}
if (!musicBuffer) {
loadAudioFile('https://www.shanebrumback./sounds/first-person-shooter-music.wav', function (buffer) {
musicBuffer = buffer;
playLoopedSound(buffer, .35);
isMusicPlaying = true;
});
} else {
if (isMusicPlaying) {
pauseSound();
isMusicPlaying = false;
} else {
resumeSound();
isMusicPlaying = true;
}
}
}
// Function to play a sound in a loop with a specific volume
function playLoopedSound(buffer, volume) {
musicSource = audioContext.createBufferSource();
musicSource.buffer = buffer;
musicSource.loop = true; // Enable looping
var gainNode = audioContext.createGain();
gainNode.gain.setValueAtTime(0, audioContext.currentTime); // Set initial volume to 0
gainNode.gain.linearRampToValueAtTime(volume, audioContext.currentTime + 2); // Gradually increase volume to desired level (adjust time as needed)
musicSource.connect(gainNode);
gainNode.connect(audioContext.destination);
// Delay the start of the audio source
musicSource.start(audioContext.currentTime + 0.1); // Adjust the delay as needed
// Note: You can adjust the delay time and volume ramping to find the appropriate values that work best for your audio files.
}
// Function to pause the music
function pauseSound() {
if (musicSource) {
musicSource.stop();
musicSource.disconnect();
musicSource = null;
}
}
// Function to resume the music
function resumeSound() {
if (musicBuffer) {
playLoopedSound(musicBuffer, .35);
}
}
// Function to play the laser sound
function playLaserSound() {
if (!audioContext) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
}
if (!laserSoundBuffer) {
loadAudioFile('https://www.shanebrumback./sounds/laser.wav', function (buffer) {
laserSoundBuffer = buffer;
playSound(buffer, 1);
});
} else {
playSound(laserSoundBuffer, 1);
}
}
// Function to play the explosion sound
function playExplosionSound() {
if (!audioContext) {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
}
if (!explosionSoundBuffer) {
loadAudioFile('https://www.shanebrumback./sounds/explosion.wav', function (buffer) {
explosionSoundBuffer = buffer;
playSound(buffer, 0.25); // Adjust the volume here (0.5 = 50% volume)
});
} else {
playSound(explosionSoundBuffer, 0.25); // Adjust the volume here (0.5 = 50% volume)
}
}
// Function to play a sound with a specific volume
function playSound(buffer, volume) {
var source = audioContext.createBufferSource();
var gainNode = audioContext.createGain();
gainNode.gain.value = volume;
source.buffer = buffer;
source.connect(gainNode);
gainNode.connect(audioContext.destination);
source.start(0);
}
// Event listener for key press
document.addEventListener('keydown', function (event) {
if (event.key === 'm' || event.key === 'M') {
playMusic();
} else if (event.key === ' ') {
if (controls.isLocked) {
event.preventDefault(); // Prevent default action of spacebar
createParticle();
playLaserSound();
}
} else if (event.key === 'e' || event.key === 'E') {
playExplosionSound();
}
});
</script>
</body>
</html>
You have to use
euler.setFromQuaternion( camera.quaternion );
euler.y -= e.movementX/500;
euler.x -= e.movementY/500;
camera.quaternion.setFromEuler( euler );
(you can change the 500)
本文标签: javascriptFirst person shooter controls with threejsStack Overflow
版权声明:本文标题:javascript - First person shooter controls with three.js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742091303a2420282.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论