ggabcd-meshwalk
Version:
MeshWalk.js is a JS library which helps your TPS game development with three.js.
211 lines (153 loc) • 5.91 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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.2.8/es6-promise.auto.min.js"></script>
<script src="https://unpkg.com/three@0.98.0/build/three.min.js"></script>
<script src="../dist/meshwalk.js"></script>
<script>
THREE.Geometry.prototype.applyMatrix4 = THREE.Geometry.prototype.applyMatrix;
MW.install( THREE );
const loadMesh = function ( url ) {
return new Promise( function( resolve, reject ) {
const loader = new THREE.JSONLoader();
loader.load( url, function( geometry, materials ) {
resolve( {
geometry: geometry,
materials: materials
} );
} );
} );
};
var width, height, clock, scene, camera, renderer;
var ambientLight, terrainMesh, characterMesh, box, sphere;
var world, min, max, partition, region,
playerRadius = 1, playerObjectHolder, playerController;
var keyInputControl;
var tpsCameraControls;
var animationController;
var eventDispatcher = new THREE.EventDispatcher();
world = new MW.World();
min = new THREE.Vector3( -15, -15, -15 );
max = new THREE.Vector3( 15, 15, 15 );
partition = 5;
region = new MW.Octree( min, max, partition );
world.add( region );
width = window.innerWidth;
height = window.innerHeight;
clock = new THREE.Clock();
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 );
camera.position.set( 0, 0, 8 );
renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
document.body.appendChild( renderer.domElement );
ambientLight = new THREE.AmbientLight( 0xffffff )
scene.add( ambientLight );
playerObjectHolder = new THREE.Object3D();
playerObjectHolder.position.set( 0, 10, 0 );
scene.add( playerObjectHolder );
sphere = new THREE.Mesh(
new THREE.SphereGeometry( playerRadius, 8, 8 ),
new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true} )
);
playerObjectHolder.add( sphere );
playerController = new MW.CharacterController( playerObjectHolder, playerRadius );
world.add( playerController );
keyInputControl = new MW.KeyInputControl();
tpsCameraControls = new MW.TPSCameraControls(
camera, // three.js camera
playerObjectHolder, // tracking object
renderer.domElement
);
// bind events
keyInputControl.addEventListener( 'movekeyon', function () { playerController.isRunning = true; } );
keyInputControl.addEventListener( 'movekeyoff', function () { playerController.isRunning = false; } );
keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } );
// synk with keybord input and camera control input
keyInputControl.addEventListener( 'movekeychange', function () {
var cameraFrontAngle = tpsCameraControls.frontAngle;
var characterFrontAngle = keyInputControl.frontAngle;
playerController.direction = cameraFrontAngle + characterFrontAngle;
} );
// 'updated' event is fired by `tpsCameraControls.update()`
tpsCameraControls.addEventListener( 'update', function () {
var cameraFrontAngle = tpsCameraControls.frontAngle;
var characterFrontAngle = keyInputControl.frontAngle;
playerController.direction = cameraFrontAngle + characterFrontAngle;
} );
Promise.all( [
loadMesh( 'terrain.json' ),
loadMesh( 'model/miku.json' )
] ).then( function( result ) {
var terrainData = result[ 0 ];
var characterData = result[ 1 ];
box = new THREE.Mesh(
new THREE.BoxGeometry( 14, 1, 5 ),
new THREE.MeshNormalMaterial()
);
box.position.set( - 3, 7.5, - 13 );
scene.add( box );
region.importThreeMesh( box );
terrainMesh = new THREE.Mesh(
terrainData.geometry,
new THREE.MeshNormalMaterial()
// new THREE.MeshFaceMaterial( terrainData.materials )
);
terrainMesh.scale.set( 2, 2, 2 );
scene.add( terrainMesh );
region.importThreeMesh( terrainMesh );
tpsCameraControls.colliderMeshes.push( terrainMesh );
characterData.materials.forEach( function ( material ) {
material.skinning = true;
} );
characterMesh = new THREE.SkinnedMesh(
characterData.geometry,
new THREE.MeshFaceMaterial( characterData.materials )
);
scene.add( characterMesh );
animationController = new MW.AnimationController( characterMesh );
animationController.motion.jump.setLoop( THREE.LoopOnce, 0 );
animationController.motion.slide.setLoop( THREE.LoopOnce, 0 );
animationController.motion.jump.clampWhenFinished = true;
animationController.motion.slide.clampWhenFinished = true;
// player motion
playerController.addEventListener( 'startIdling', function () { animationController.play( 'idle' ); } );
playerController.addEventListener( 'startWalking', function () { animationController.play( 'run' ); } );
playerController.addEventListener( 'startJumping', function () { animationController.play( 'jump' ); } );
playerController.addEventListener( 'startSliding', function () { animationController.play( 'slide' ); } );
playerController.addEventListener( 'startFalling', function () { animationController.play( 'slide' ); } );
eventDispatcher.addEventListener( 'beforerender', function () {
animationController.mesh.position.set(
playerController.center.x,
playerController.center.y - playerController.radius,
playerController.center.z
);
animationController.mesh.rotation.y = playerController.direction + Math.PI;
} );
( function update () {
const delta = clock.getDelta();
requestAnimationFrame( update );
world.step( Math.min( delta, 0.02 ) );
tpsCameraControls.update( delta );
animationController.update( delta );
eventDispatcher.dispatchEvent( { type: 'beforerender' } );
renderer.render( scene, camera );
} )();
} );
</script>
</body>
</html>