Skip to content

Commit

Permalink
Examples: Refactor FPS demo
Browse files Browse the repository at this point in the history
  • Loading branch information
Mugen87 committed Oct 5, 2018
1 parent beefb9d commit d35d285
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 259 deletions.
31 changes: 14 additions & 17 deletions examples/entity/shooter/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@
import * as THREE from '../../lib/three.module.js';
import { GLTFLoader } from '../../lib/GLTFLoader.module.js';

import { FirstPersonControls } from './src/FirstPersonControls.js';
import { Player } from './src/Player.js';

let camera, scene, renderer;

let entityManager, time, player;
let entityManager, time, controls;

init();
animate();
Expand Down Expand Up @@ -127,7 +128,7 @@

intro.addEventListener( 'click', function ( event ) {

player.connect();
controls.connect();

}, false );

Expand All @@ -136,27 +137,21 @@
entityManager = new YUKA.EntityManager();
time = new YUKA.Time();

player = new Player();
player.lookSpeed = 2;
const player = new Player();
player.height = 2;
player.maxSpeed = 40;
player.head.setRenderComponent( camera, syncCamera );
player.weapon.sounds.set( 'shot', shot );

player.onActive = () => { intro.classList.add( 'hidden' ) };
player.onInactive = () => { intro.classList.remove( 'hidden' ) };
player.onAudio = ( id ) => {
controls = new FirstPersonControls( player );
controls.lookSpeed = 2;
controls.setRotation( - 2.2, 0.2 );

if ( id === 'rightStep' ) step1.play();
if ( id === 'leftStep' ) step2.play();
if ( id === 'shot' ) {
controls.sounds.set( 'rightStep', step1 );
controls.sounds.set( 'leftStep', step2 );

if ( shot.isPlaying === true ) shot.stop();

shot.play();

}

};
controls.addEventListener( 'lock', ( event ) => { intro.classList.add( 'hidden' ) } );
controls.addEventListener( 'unlock', ( event ) => { intro.classList.remove( 'hidden' ) } );

entityManager.add( player );

Expand All @@ -177,6 +172,8 @@

const delta = time.update().getDelta();

controls.update( delta );

entityManager.update( delta );

renderer.render( scene, camera );
Expand Down
12 changes: 10 additions & 2 deletions examples/entity/shooter/src/Blaster.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Blaster extends Weapon {
this.maxAmmo = 40;
this.shotTime = 0.2;

this.sounds = new Map();

}

shoot() {
Expand All @@ -24,9 +26,15 @@ class Blaster extends Weapon {

this.status = Weapon.STATUS.SHOT;

// shot
// audio

const audio = this.sounds.get( 'shot' );

if ( audio.isPlaying === true ) audio.stop();

if ( this.owner.onAudio ) this.owner.onAudio( 'shot' );
audio.play();

//

this.roundsLeft --;

Expand Down
256 changes: 256 additions & 0 deletions examples/entity/shooter/src/FirstPersonControls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
/**
* @author Mugen87 / https://github.com/Mugen87
*/

import { EventDispatcher, Vector3, Logger } from '../../../../build/yuka.module.js';

const PI05 = Math.PI / 2;
const direction = new Vector3();
const velocity = new Vector3();

let currentSign = 1;
let elapsedTime = 0;

class FirstPersonControls extends EventDispatcher {

constructor( owner = null ) {

super();

this.owner = owner;

this.movementX = 0; // mouse left/right
this.movementY = 0; // mouse up/down

this.lookingSpeed = 1;
this.brakingPower = 10;
this.headMovement = 1.5;

this.input = {
forward: false,
backward: false,
right: false,
left: false
};

this.sounds = new Map();

this._mouseDownHandler = onMouseDown.bind( this );
this._mouseMoveHandler = onMouseMove.bind( this );
this._pointerlockChangeHandler = onPointerlockChange.bind( this );
this._pointerlockErrorHandler = onPointerlockError.bind( this );
this._keyDownHandler = onKeyDown.bind( this );
this._keyUpHandler = onKeyUp.bind( this );

}

connect() {

document.addEventListener( 'mousedown', this._mouseDownHandler, false );
document.addEventListener( 'mousemove', this._mouseMoveHandler, false );
document.addEventListener( 'pointerlockchange', this._pointerlockChangeHandler, false );
document.addEventListener( 'pointerlockerror', this._pointerlockErrorHandler, false );
document.addEventListener( 'keydown', this._keyDownHandler, false );
document.addEventListener( 'keyup', this._keyUpHandler, false );

document.body.requestPointerLock();

}

disconnect() {

document.removeEventListener( 'mousedown', this._mouseDownHandler, false );
document.removeEventListener( 'mousemove', this._mouseMoveHandler, false );
document.removeEventListener( 'pointerlockchange', this._pointerlockChangeHandler, false );
document.removeEventListener( 'pointerlockerror', this._pointerlockErrorHandler, false );
document.removeEventListener( 'keydown', this._keyDownHandler, false );
document.removeEventListener( 'keyup', this._keyUpHandler, false );

}

update( delta ) {

const input = this.input;
const owner = this.owner;

velocity.x -= velocity.x * this.brakingPower * delta;
velocity.z -= velocity.z * this.brakingPower * delta;

direction.z = Number( input.forward ) - Number( input.backward );
direction.x = Number( input.left ) - Number( input.right );
direction.normalize();

if ( input.forward || input.backward ) velocity.z -= direction.z * owner.maxSpeed * delta;
if ( input.left || input.right ) velocity.x -= direction.x * owner.maxSpeed * delta;

owner.velocity.copy( velocity ).applyRotation( owner.rotation );

//

this._updateHead( delta );

}

setRotation( yaw, pitch ) {

this.movementX = yaw;
this.movementY = pitch;

this.owner.rotation.fromEuler( 0, this.movementX, 0 );
this.owner.head.rotation.fromEuler( this.movementY, 0, 0 );

}

_updateHead( delta ) {

const owner = this.owner;
const head = owner.head;

// some simple head bobbing

const speed = owner.getSpeed();

elapsedTime += delta * speed; // scale delta with movement speed

const motion = Math.sin( elapsedTime * this.headMovement );

head.position.y = Math.abs( motion ) * 0.06;
head.position.x = motion * 0.08;

//

head.position.y += owner.height;

//

const sign = Math.sign( Math.cos( elapsedTime * this.headMovement ) );

if ( sign < currentSign ) {

currentSign = sign;

const audio = this.sounds.get( 'rightStep' );
audio.play();

}

if ( sign > currentSign ) {

currentSign = sign;

const audio = this.sounds.get( 'leftStep' );
audio.play();

}

}

}

// handler

function onMouseDown( event ) {

if ( event.which === 1 ) {

this.owner.weapon.shoot();

} else if ( event.which === 3 ) {

this.owner.weapon.reload();

}

}

function onMouseMove( event ) {

this.movementX -= event.movementX * 0.001 * this.lookingSpeed;
this.movementY -= event.movementY * 0.001 * this.lookingSpeed;

this.movementY = Math.max( - PI05, Math.min( PI05, this.movementY ) );

this.owner.rotation.fromEuler( 0, this.movementX, 0 ); // yaw
this.owner.head.rotation.fromEuler( this.movementY, 0, 0 ); // pitch

}

function onPointerlockChange() {

if ( document.pointerLockElement === document.body ) {

this.dispatchEvent( { type: 'lock' } );

} else {

this.disconnect();

this.dispatchEvent( { type: 'unlock' } );

}

}

function onPointerlockError() {

Logger.warn( 'YUKA.Player: Unable to use Pointer Lock API.' );

}

function onKeyDown( event ) {

switch ( event.keyCode ) {

case 38: // up
case 87: // w
this.input.forward = true;
break;

case 37: // left
case 65: // a
this.input.left = true;
break;

case 40: // down
case 83: // s
this.input.backward = true;
break;

case 39: // right
case 68: // d
this.input.right = true;
break;

}

}

function onKeyUp() {

switch ( event.keyCode ) {

case 38: // up
case 87: // w
this.input.forward = false;
break;

case 37: // left
case 65: // a
this.input.left = false;
break;

case 40: // down
case 83: // s
this.input.backward = false;
break;

case 39: // right
case 68: // d
this.input.right = false;
break;

}

}

export { FirstPersonControls };
Loading

0 comments on commit d35d285

Please sign in to comment.