ggabcd-meshwalk
Version:
MeshWalk.js is a JS library which helps your TPS game development with three.js.
211 lines (163 loc) • 6.13 kB
HTML
<html>
<head>
<meta charset="utf-8">
<title>=^.^=</title>
<style>
body{margin: 0;padding: 0; background: #000;}
canvas{display: block;}
.info{
color: #fff;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="info">
`maxSlopeGradient` is changable:
<select onchange="setMaxSlopeGradient( this.value * 1 )">
<option value="30">30deg</option>
<option value="50" selected>50deg</option>
<option value="70">70deg</option>
</select><br>
WASD to move, Space to jump. Plus, mousedrag to rotate, scroll to zoom
</div>
<script type="module">
import * as THREE from 'https://unpkg.com/three@0.120.0/build/three.module.js';
import * as MW from '../dist/meshwalk.module.js';
// See demo/2_keyboardInput.html first
MW.install( THREE );
const world = new MW.World();
const min = new THREE.Vector3( - 50, - 50, - 50 );
const max = new THREE.Vector3( 50, 50, 50 );
const partition = 5;
const region = new MW.Octree( min, max, partition );
world.add( region );
const width = window.innerWidth;
const height = window.innerHeight;
const clock = new THREE.Clock();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 );
camera.position.set( 0, 0, 8 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
document.body.appendChild( renderer.domElement );
const light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 1, 1, 1 );
scene.add( light );
const ground = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 100, 100, 10, 10 ),
new THREE.MeshNormalMaterial()
);
ground.rotation.x = - 90 * THREE.Math.DEG2RAD;
scene.add( ground );
region.importThreeMesh( ground );
const groundHelper = new THREE.WireframeHelper( ground );
groundHelper.rotation.copy( ground.rotation );
scene.add( groundHelper );
const object1 = new THREE.Mesh(
new THREE.CylinderGeometry( 5, 5, 4, 32 ),
new THREE.MeshNormalMaterial()
);
object1.position.set( 0, 2, 0 );
scene.add( object1 );
region.importThreeMesh( object1 );
const object1Helper = new THREE.WireframeHelper( object1 );
object1Helper.position.copy( object1.position );
object1Helper.rotation.copy( object1.rotation );
scene.add( object1Helper );
const object2 = new THREE.Mesh(
new THREE.BoxGeometry( 5, 2, 14 ),
new THREE.MeshNormalMaterial()
);
object2.position.set( - 15, 0, 0 );
object2.rotation.set( 20 * THREE.Math.DEG2RAD, 0, 0 );
scene.add( object2 );
region.importThreeMesh( object2 );
const object2Helper = new THREE.WireframeHelper( object2 );
object2Helper.position.copy( object2.position );
object2Helper.rotation.copy( object2.rotation );
scene.add( object2Helper );
const object3 = new THREE.Mesh(
new THREE.BoxGeometry( 5, 2, 10 ),
new THREE.MeshNormalMaterial()
);
object3.position.set( - 15, 4.5, - 8 );
object3.rotation.set( 40 * THREE.Math.DEG2RAD, 0, 0 );
scene.add( object3 );
region.importThreeMesh( object3 );
const object3Helper = new THREE.WireframeHelper( object3 );
object3Helper.position.copy( object3.position );
object3Helper.rotation.copy( object3.rotation );
scene.add( object3Helper );
const object4 = new THREE.Mesh(
new THREE.BoxGeometry( 5, 2, 10 ),
new THREE.MeshNormalMaterial()
);
object4.position.set( - 15, 10.5, - 13 );
object4.rotation.set( 60 * THREE.Math.DEG2RAD, 0, 0 );
scene.add( object4 );
region.importThreeMesh( object4 );
const object4Helper = new THREE.WireframeHelper( object4 );
object4Helper.position.copy( object4.position );
object4Helper.rotation.copy( object4.rotation );
scene.add( object4Helper );
const object5 = new THREE.Mesh(
new THREE.SphereGeometry( 10, 8, 8 ),
new THREE.MeshNormalMaterial()
);
object5.position.set( 20, 0, 0 );
scene.add( object5 );
region.importThreeMesh( object5 );
const object5Helper = new THREE.WireframeHelper( object5 );
object5Helper.position.copy( object5.position );
scene.add( object5Helper );
const playerRadius = 1;
const playerObjectHolder = new THREE.Object3D();
playerObjectHolder.position.set( 0, 10, 0 );
scene.add( playerObjectHolder );
const sphere = new THREE.Mesh(
new THREE.SphereGeometry( playerRadius, 16, 16 ),
new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true} )
);
playerObjectHolder.add( sphere );
const playerController = new MW.CharacterController( playerObjectHolder, playerRadius );
world.add( playerController );
window.setMaxSlopeGradient = ( deg ) => {
playerController.maxSlopeGradient = Math.cos( deg * THREE.Math.DEG2RAD );
};
const keyInputControl = new MW.KeyInputControl();
const tpsCameraControls = new MW.TPSCameraControls(
camera, // three.js camera
playerObjectHolder, // tracking object
renderer.domElement
);
tpsCameraControls.colliderMeshes = [ ground, object1, object2, object3, object4, object5 ];
// bind events
keyInputControl.addEventListener( 'movekeyon', () => playerController.isRunning = true );
keyInputControl.addEventListener( 'movekeyoff', () => playerController.isRunning = false );
keyInputControl.addEventListener( 'jumpkeypress', () => playerController.jump() );
// synk with keybord input and camera control input
keyInputControl.addEventListener( 'movekeychange', () => {
const cameraFrontAngle = tpsCameraControls.frontAngle;
const characterFrontAngle = keyInputControl.frontAngle;
playerController.direction = cameraFrontAngle + characterFrontAngle;
} );
// the 'updated' event is fired by `tpsCameraControls.update()`
tpsCameraControls.addEventListener( 'update', () => {
const cameraFrontAngle = tpsCameraControls.frontAngle;
const characterFrontAngle = keyInputControl.frontAngle;
playerController.direction = cameraFrontAngle + characterFrontAngle;
} );
( function update () {
const delta = clock.getDelta();
requestAnimationFrame( update );
world.step( Math.min( delta, 0.02 ) );
tpsCameraControls.update( delta );
renderer.render( scene, camera );
} )();
</script>
</body>
</html>