/** * * @param id * @param name * @constructor */ GameLib.D3.ComponentFlyControls = function ComponentFlyControls( id, name ) { this.id = id || GameLib.D3.Tools.RandomId(); if (typeof name == 'undefined') { name = this.constructor.name; } this.name = name; this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. GameLib.D3.Utils.Extend(GameLib.D3.ComponentFlyControls, GameLib.D3.ComponentInterface); // Component fields this.pitch = 0; this.yaw = 0; this.canRotate = false; this.moveSpeed = 22.2; this.moveForward = false; this.moveBackward = false; this.moveLeft = false; this.moveRight = false; this.moveUp = false; this.moveDown = false; }; ///////////////////////// Methods to override ////////////////////////// GameLib.D3.ComponentFlyControls.prototype.onUpdate = function( deltaTime, parentEntity ) { // Apply rotation var rotation = new THREE.Euler( this.pitch, this.yaw, 0, "YXZ" ); var quat = new THREE.Quaternion().setFromEuler( rotation ); parentEntity.quaternion.x = quat.x; parentEntity.quaternion.y = quat.y; parentEntity.quaternion.z = quat.z; parentEntity.quaternion.w = quat.w; // Apply translation var direction = new THREE.Vector3(0, 0, -1); direction = direction.applyEuler(rotation).normalize(); if(this.moveForward) { parentEntity.position.x += direction.x * (deltaTime * this.moveSpeed); parentEntity.position.y += direction.y * (deltaTime * this.moveSpeed); parentEntity.position.z += direction.z * (deltaTime * this.moveSpeed); } else if(this.moveBackward) { parentEntity.position.x -= direction.x * (deltaTime * this.moveSpeed); parentEntity.position.y -= direction.y * (deltaTime * this.moveSpeed); parentEntity.position.z -= direction.z * (deltaTime * this.moveSpeed); } if(this.moveLeft) { var right = direction.cross(new THREE.Vector3(0, 1, 0)); parentEntity.position.x -= right.x * (deltaTime * this.moveSpeed); parentEntity.position.y -= right.y * (deltaTime * this.moveSpeed); parentEntity.position.z -= right.z * (deltaTime * this.moveSpeed); } else if(this.moveRight) { var right = direction.cross(new THREE.Vector3(0, 1, 0)); parentEntity.position.x += right.x * (deltaTime * this.moveSpeed); parentEntity.position.y += right.y * (deltaTime * this.moveSpeed); parentEntity.position.z += right.z * (deltaTime * this.moveSpeed); } // Absolute Y-Axis if(this.moveUp) { parentEntity.position.y += (deltaTime * this.moveSpeed); } else if(this.moveDown) { parentEntity.position.y -= (deltaTime * this.moveSpeed); } }; /** * * @param parentScene * @param parentEntity */ GameLib.D3.ComponentFlyControls.prototype.onSetParentEntity = function( parentScene, parentEntity ) { var component = this; // Lock cursor var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; var element = document.body; document.addEventListener('click', function(event) { if(havePointerLock) { if(event.button == 0) { component.canRotate = true; element.requestPointerLock(); } else if(event.button == 2) { component.canRotate = false; document.exitPointerLock(); } } }); if(havePointerLock) { element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; } // Swipe document.addEventListener('touchstart', function(evt) { component.xDown = evt.touches[0].clientX; component.yDown = evt.touches[0].clientY; }, false); document.addEventListener('touchmove', function(evt) { if ( ! component.xDown || ! component.yDown ) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; var xDiff = component.xDown - xUp; var yDiff = component.yDown - yUp; if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/ if ( xDiff > 0 ) { /* left swipe */ } else { /* right swipe */ } } else { if ( yDiff > 0 ) { /* up swipe */ } else { /* down swipe */ } } component.yaw -= xDiff * 0.002; component.pitch -= yDiff * 0.002; }, false); // Mouse move document.addEventListener('mousemove', function (event) { if(component.canRotate) { var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; component.yaw -= movementX * 0.002; component.pitch -= movementY * 0.002; } // Save mouseCoords sys.mouseCoords.set( (event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1 ); }, false); // Hook up keyboard controls document.addEventListener('keydown', function (event) { switch (event.keyCode) { case 87: // w component.moveForward = true; break; case 65: // a component.moveLeft = true; break; case 83: // s component.moveBackward = true; break; case 68: // d component.moveRight = true; break; case 32: // space component.moveUp = true; break; case 16: component.moveDown = true; break; } }, false); document.addEventListener('keyup', function (event) { switch (event.keyCode) { case 38: // up case 87: // w component.moveForward = false; break; case 37: // left case 65: // a component.moveLeft = false; break; case 40: // down case 83: // s component.moveBackward = false; break; case 39: // right case 68: // d component.moveRight = false; break; case 32: // space component.moveUp = false; break; case 16: component.moveDown = false; break; } }, false); };