Skip to content

Commit

Permalink
Examples: Enhance FPS demo
Browse files Browse the repository at this point in the history
  • Loading branch information
Mugen87 committed Oct 5, 2018
1 parent d35d285 commit ac17e31
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 26 deletions.
Binary file added examples/entity/shooter/audio/reload.ogg
Binary file not shown.
106 changes: 99 additions & 7 deletions examples/entity/shooter/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@
#intro.hidden {
display: none;
}
#crosshairs {
position: absolute;
top: 50%;
left: 50%;
width: 10px;
height: 10px;
border-radius: 66px;
border: 2px solid #ffffff;
opacity: 0.5;
}
#crosshairs.hidden {
display: none;
}
</style>
</head>
<body>
Expand All @@ -31,6 +44,8 @@
Click to Play
</section>

<section id="crosshairs" class="hidden"></section>

<script type="module">

import * as YUKA from '../../../build/yuka.module.js';
Expand All @@ -40,7 +55,7 @@
import { FirstPersonControls } from './src/FirstPersonControls.js';
import { Player } from './src/Player.js';

let camera, scene, renderer;
let camera, scene, renderer, mixer;

let entityManager, time, controls;

Expand Down Expand Up @@ -69,7 +84,7 @@
ground.updateMatrix();
scene.add( ground );

var grid = new THREE.GridHelper( 50, 25, 0x000000, 0x000000 );
const grid = new THREE.GridHelper( 50, 25, 0x000000, 0x000000 );
grid.matrixAutoUpdate = false;
grid.material.opacity = 0.2;
grid.material.transparent = true;
Expand Down Expand Up @@ -99,6 +114,10 @@
scene.add( weaponMesh );
weaponMesh.add( shot );

mixer = new THREE.AnimationMixer( player.weapon );

buildAnimations( player.weapon );

} );

//
Expand All @@ -110,10 +129,12 @@
const step1 = new THREE.Audio( listener );
const step2 = new THREE.Audio( listener );
const shot = new THREE.PositionalAudio( listener );
const reload = new THREE.PositionalAudio( listener );

audioLoader.load( 'audio/step1.ogg', ( buffer ) => { step1.setBuffer( buffer ) } );
audioLoader.load( 'audio/step2.ogg', ( buffer ) => { step2.setBuffer( buffer ) } );
audioLoader.load( 'audio/shot.ogg', ( buffer ) => { shot.setBuffer( buffer ) } );
audioLoader.load( 'audio/reload.ogg', ( buffer ) => { reload.setBuffer( buffer ) } );

//

Expand All @@ -125,6 +146,7 @@
window.addEventListener( 'resize', onWindowResize, false );

const intro = document.getElementById( 'intro' );
const crosshairs = document.getElementById( 'crosshairs' );

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

Expand All @@ -138,20 +160,28 @@
time = new YUKA.Time();

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

controls = new FirstPersonControls( player );
controls.lookSpeed = 2;
controls.setRotation( - 2.2, 0.2 );

controls.sounds.set( 'rightStep', step1 );
controls.sounds.set( 'leftStep', step2 );

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

intro.classList.add( 'hidden' ) ;
crosshairs.classList.remove( 'hidden' );

} );
controls.addEventListener( 'unlock', ( event ) => {

intro.classList.remove( 'hidden' );
crosshairs.classList.add( 'hidden' );

} );

entityManager.add( player );

Expand All @@ -176,6 +206,8 @@

entityManager.update( delta );

if ( mixer ) mixer.update( delta );

renderer.render( scene, camera );

}
Expand All @@ -192,6 +224,66 @@

}

function buildAnimations( weapon ) {

// manually create some keyframes for testing

let positionKeyframes, rotationKeyframes;
let q0, q1, q2;

// shot

positionKeyframes = new THREE.VectorKeyframeTrack( '.position', [ 0, 0.05, 0.15, 0.3 ], [
0.3, - 0.3, - 1,
0.3, - 0.2, - 0.7,
0.3, - 0.305, - 1,
0.3, - 0.3, - 1 ]
);

q0 = new THREE.Quaternion();
q1 = new THREE.Quaternion().setFromAxisAngle( new THREE.Vector3( 1, 0, 0 ), 0.2 );
q2 = new THREE.Quaternion().setFromAxisAngle( new THREE.Vector3( 1, 0, 0 ), - 0.02 );

rotationKeyframes = new THREE.QuaternionKeyframeTrack( '.rotation', [ 0, 0.05, 0.15, 0.3 ], [
q0.x, q0.y, q0.z, q0.w,
q1.x, q1.y, q1.z, q1.w,
q2.x, q2.y, q2.z, q2.w,
q0.x, q0.y, q0.z, q0.w ]
);

const shotClip = new THREE.AnimationClip( 'Shot', weapon.shotTime, [ positionKeyframes, rotationKeyframes ] );
const shotAction = mixer.clipAction( shotClip );
shotAction.loop = THREE.LoopOnce;

weapon.animations.set( 'shot', shotAction );

// reload

positionKeyframes = new THREE.VectorKeyframeTrack( '.position', [ 0, 0.2, 1.3, 1.5 ], [
0.3, - 0.3, - 1,
0.3, - 0.6, - 1,
0.3, - 0.6, - 1,
0.3, - 0.3, - 1 ]
);

q1 = new THREE.Quaternion().setFromAxisAngle( new THREE.Vector3( 1, 0, 0 ), - 0.4 );

rotationKeyframes = new THREE.QuaternionKeyframeTrack( '.rotation', [ 0, 0.2, 1.3, 1.5 ], [
q0.x, q0.y, q0.z, q0.w,
q1.x, q1.y, q1.z, q1.w,
q1.x, q1.y, q1.z, q1.w,
q0.x, q0.y, q0.z, q0.w ]
);

const reloadClip = new THREE.AnimationClip( 'Shot', weapon.reloadTime, [ positionKeyframes, rotationKeyframes ] );
const reloadAction = mixer.clipAction( reloadClip );
reloadAction.loop = THREE.LoopOnce;

weapon.animations.set( 'reload', reloadAction );


}

</script>

</body>
Expand Down
64 changes: 60 additions & 4 deletions examples/entity/shooter/src/Blaster.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,66 @@ class Blaster extends Weapon {

super( owner );

this.roundsLeft = 5;
this.roundsPerClip = 5;
this.ammo = 20;
this.maxAmmo = 40;
this.roundsLeft = 12;
this.roundsPerClip = 12;
this.ammo = 24;
this.maxAmmo = 48;
this.shotTime = 0.2;
this.reloadTime = 1.5;

this.animations = new Map();
this.sounds = new Map();

}

reload() {

if ( this.status === Weapon.STATUS.READY || this.status === Weapon.STATUS.EMPTY ) {

this.status = Weapon.STATUS.RELOAD;

// audio

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

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

audio.play();

// animation

const animation = this.animations.get( 'reload' );
animation.stop();
animation.play();

//

this._timeOutId = setTimeout( () => {

const toReload = this.roundsPerClip - this.roundsLeft;

if ( this.ammo >= toReload ) {

this.roundsLeft = this.roundsPerClip;
this.ammo -= toReload;

} else {

this.roundsLeft = this.ammo;
this.ammo = 0;

}

this.status = Weapon.STATUS.READY;

}, this.reloadTime * 1000 );

}

return this;

}

shoot() {

if ( this.status === Weapon.STATUS.READY ) {
Expand All @@ -34,6 +84,12 @@ class Blaster extends Weapon {

audio.play();

// animation

const animation = this.animations.get( 'shot' );
animation.stop();
animation.play();

//

this.roundsLeft --;
Expand Down
35 changes: 21 additions & 14 deletions examples/entity/shooter/src/FirstPersonControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class FirstPersonControls extends EventDispatcher {

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

this.input = {
forward: false,
Expand Down Expand Up @@ -87,7 +87,13 @@ class FirstPersonControls extends EventDispatcher {

//

this._updateHead( delta );
const speed = owner.getSpeed();
elapsedTime += delta * speed; // scale delta with movement speed

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

this._updateHead( motion );
this._updateWeapon( motion );

}

Expand All @@ -101,24 +107,15 @@ class FirstPersonControls extends EventDispatcher {

}

_updateHead( delta ) {
_updateHead( motion ) {

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.x = motion * 0.14;
head.position.y = Math.abs( motion ) * 0.12;
head.position.y += owner.height;

//
Expand All @@ -145,6 +142,16 @@ class FirstPersonControls extends EventDispatcher {

}

_updateWeapon( motion ) {

const owner = this.owner;
const weaponContainer = owner.weaponContainer;

weaponContainer.position.x = motion * 0.005;
weaponContainer.position.y = Math.abs( motion ) * 0.002;

}

}

// handler
Expand Down
8 changes: 7 additions & 1 deletion examples/entity/shooter/src/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ class Player extends MovingEntity {
this.head = new GameEntity();
this.add( this.head );

this.weaponContainer = new GameEntity();
this.head.add( this.weaponContainer );

this.weapon = new Blaster( this );
this.head.add( this.weapon );
this.weaponContainer.add( this.weapon );

this.weapon.position.set( 0.3, - 0.3, - 1 );

//

this.maxSpeed = 80;
this.updateOrientation = false;

}
Expand Down

0 comments on commit ac17e31

Please sign in to comment.