UNPKG

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
<!DOCTYPE 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>