GameDev2:Physics/First Person Example
From Bold Idea Knowledgebase
This example demonstrates the following:
- How to create a first-person POV player object that responds to physics and can interact w/ real-world objects
- How to control a physics player using pointer-lock and typical WASD movement
Click here for a copy of PointerLockControls.js
<html><head><link rel="stylesheet" type="text/css" href="css/style.css"></head>
<body>
<!-- Include other libraries here (keep three.js at the top): -->
<script src="js/Three.js"></script>
<script src="js/physi.js"></script>
<script src="js/PointerLockControls.js"></script>
<script src="js/Door.js"></script>
<script>
// Add variables that are defined in other libraries below to avoid warnings:
/* global THREE, Scoreboard, Physijs */
Physijs.scripts.worker = 'js/physijs_worker.js';
Physijs.scripts.ammo = 'ammo.js';
// ****** START CODING HERE! ******
// Set our width and height
var width = window.innerWidth, height = window.innerHeight;
// Create your scene.
var scene = new Physijs.Scene();
// Set up the camera
var camera = new THREE.PerspectiveCamera(70, width/height);
// Set up the renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width, height);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
/**
* Basic pointer-lock controls
*
* See https://threejs.org/examples/misc_controls_pointerlock.html for a more
* complete example of pointer-lock
*
* Note: don't copy WASD control from that example as it doesn't work w/ physics
*/
var controls = new THREE.PointerLockControls(camera);
document.body.addEventListener('click', function() {
document.body.requestPointerLock();
controls.enabled = true;
});
// *** ADD 3D OBJECTS TO YOUR SCENE HERE ***
/**
* Player object setup
*/
var playerHeight = 6;
// We use a capsueMesh so that the player can move over un-even terrain
var player = new Physijs.CapsuleMesh(
new THREE.CylinderGeometry(1, 1, playerHeight),
new THREE.MeshNormalMaterial()
);
player.position.set(-10, -20, 0);
player.visible = false;
// Use the controls object as the player's POV
var pov = controls.getObject();
player.add(pov);
pov.position.set(0, (playerHeight / 10), 0);
scene.add(player);
/**
* Player WASD Controls
*/
// Keep track of W, A, S, D keypresses
var keyW = false;
var keyA = false;
var keyS = false;
var keyD = false;
document.addEventListener('keydown', function(event) {
if (event.keyCode == 87) keyW = true;
if (event.keyCode == 65) keyA = true;
if (event.keyCode == 83) keyS = true;
if (event.keyCode == 68) keyD = true;
});
document.addEventListener('keyup', function(event) {
if (event.keyCode == 87) keyW = false;
if (event.keyCode == 65) keyA = false;
if (event.keyCode == 83) keyS = false;
if (event.keyCode == 68) keyD = false;
});
// Note: this function should be called during animate()
function controlPlayer() {
// Change this to the speed you want your player to move
var speed = 10;
// Our player is a pill shape, so this keeps our player from accidentally tipping over
player.setAngularFactor({ x: 0, y: 0, z: 0 });
// We want to rotate our vector around the Y axis
var rotateAxis = new THREE.Vector3(0, 1, 0);
if (keyW || keyA || keyS || keyD) {
// Get a vector based on our direction
// create vectors for each direction
var vectorFwd = controls.getDirection();
var vectorLeft = controls.getDirection();
var vectorRight = controls.getDirection();
var vectorBack = controls.getDirection();
vectorLeft.applyAxisAngle(rotateAxis, Math.PI / 2);
vectorRight.applyAxisAngle(rotateAxis,-Math.PI / 2);
vectorBack.applyAxisAngle(rotateAxis, Math.PI);
var vector = new THREE.Vector3();
if (keyW) vector.add(vectorFwd);
if (keyA) vector.add(vectorLeft);
if (keyS) vector.add(vectorBack);
if (keyD) vector.add(vectorRight);
// apply speed to our vector
vector.normalize();
vector.multiplyScalar(speed);
// If you don't want to allow the player to "fly", set to current Y velocity
vector.y = player.getLinearVelocity().y;
// now we just set the velocity to that vector
player.setLinearVelocity(vector);
// set a flag to indicate that our player is moving
player.isMoving = true;
} else {
// if no keys are , but player is still moving, slow the player down to a halt.
if (player.isMoving) {
var vector = player.getLinearVelocity();
vector.normalize();
player.setLinearVelocity(vector);
player.isMoving = false;
}
}
}
/**
* Scene objects
*/
// Our floor has mass of 0 so it doesn't fall w/ gravity
var floor = new Physijs.BoxMesh(
new THREE.BoxGeometry(50, 1, 50),
new THREE.MeshBasicMaterial({color: 0xCCCCCC}),
0
);
floor.position.set(0, -26, 0);
scene.add(floor);
// Add a ball
var ball = new Physijs.SphereMesh(
new THREE.SphereGeometry(2, 10, 10),
new THREE.MeshNormalMaterial()
);
ball.position.set(0, -20, -10);
scene.add(ball);
// Add a fixed box to demonstrate how you can walk over it
// (because our player uses CapsuleMesh)
var box = new Physijs.BoxMesh(
new THREE.BoxGeometry(5, .25, 5),
new THREE.MeshNormalMaterial(),
0
)
box.position.set(0, -25, 0);
scene.add(box);
function animate() {
// Use this function to animate your objects.
// This function runs over 60 times per second!
// *** ANIMATE YOUR 3D OBJECTS HERE ****
renderer.render(scene, camera);
requestAnimationFrame(animate);
scene.simulate();
controlPlayer();
}
animate();
</script>
</body></html>