Skip to content

Commit

Permalink
extended-wasd-controls and joysticks update
Browse files Browse the repository at this point in the history
Big update for extended-wasd-controls component. Should work seamlessly with look-controls; refactored code allows for integrating joystick controls. Update includes multiple examples illustrating various use cases.
  • Loading branch information
stemkoski committed Jun 12, 2020
1 parent c3508d5 commit ca06ab8
Show file tree
Hide file tree
Showing 15 changed files with 591 additions and 73 deletions.
4 changes: 2 additions & 2 deletions extended-wasd-controls.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

<!--
create a camera entity; not adding default wasd-controls.
if desired, look-controls component can be added to camera, provided that
"coordinateLookControls: true;" included in extendend-wasd-controls
if desired, look-controls component can be added to camera,
which automatically sets turnEnabled/lookEnabled to false
-->
<a-entity id="camera" camera
position="0 1.6 0"
Expand Down
Binary file added images/demo/screen-controls-joystick-dual.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/demo/screen-controls-joystick-look.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/joystick-base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/joystick-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/joystick-green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/joystick-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/joystick-yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 27 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,39 @@
<img src="images/demo/extended-wasd-controls.png" class="demo-image"/></a></td>
<td class="demo-title"><a href="extended-wasd-controls.html">Extended WASD Controls</a></td></tr>
<tr><td class="demo-text">
Introduces an "extended WASD controls" component for desktop (keyboard) that enables the user to: <br/> <li>turn left/right (Q/E) <br/> <li>fly up/down (R/F) <br/> <li>look up/down (T/G) <br/> Controls and settings are completely customizable; can be applied to camera or other entities.
Introduces an "extended WASD controls" component for desktop (keyboard) that enables the user to: <br/>
<li>move forward/left/backward/right (W/A/S/D) <br/>
<li>turn left/right (Q/E) <br/>
<li>fly up/down (R/F) <br/>
<li>look up/down (T/G) <br/>
Controls and settings are completely customizable; can be applied to camera or other entities.
</td></tr>
</table>

<table class="demo-table">
<tr><td rowspan="2"><a href="screen-controls.html">
<tr><td rowspan="2"><a href="screen-controls-buttons-look.html">
<img src="images/demo/screen-controls.png" class="demo-image"/></a></td>
<td class="demo-title"><a href="screen-controls.html">Screen Controls</a></td></tr>
<td class="demo-title"><a href="screen-controls-buttons-look.html">Screen Controls (Buttons/Look)</a></td></tr>
<tr><td class="demo-text">
Incorporating on-screen controls (optimized for touchscreen/tablet devices, but also works on desktop) that are integrated the the "extended WASD controls" component. Also demonstrates integration of the extended-wasd-controls component (movement only) with the look-controls component.
Incorporating on-screen button controls for movement (optimized for touchscreen/tablet devices; also supports desktop) with the "extended WASD controls" component and the look-controls component (supports "magic screen" effect as well as desktop).
</td></tr>
</table>

<table class="demo-table">
<tr><td rowspan="2"><a href="screen-controls-joystick-look.html">
<img src="images/demo/screen-controls-joystick-look.png" class="demo-image"/></a></td>
<td class="demo-title"><a href="screen-controls-joystick-look.html">Screen Controls (Joystick/Look)</a></td></tr>
<tr><td class="demo-text">
Incorporating on-screen joystick controls for movement (optimized for touchscreen/tablet devices; also supports desktop) with the "extended WASD controls" component and the look-controls component (supports "magic screen" effect as well as desktop).
</td></tr>
</table>

<table class="demo-table">
<tr><td rowspan="2"><a href="screen-controls-joystick-dual.html">
<img src="images/demo/screen-controls-joystick-dual.png" class="demo-image"/></a></td>
<td class="demo-title"><a href="screen-controls-joystick-dual.html">Screen Controls (Dual Joysticks)</a></td></tr>
<tr><td class="demo-text">
Incorporating dual on-screen joystick controls for movement and turn/look (optimized for touchscreen/tablet devices; also supports desktop) with the "extended WASD controls" component.
</td></tr>
</table>

Expand Down
63 changes: 63 additions & 0 deletions joystick-basic.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>

<head>
<title>Joystick Controls</title>
<script src="js/joystick.js"></script>
<style>
body
{
font-family: Courier, monospaced;
font-size: 16px;
font-weight: bold;
}
</style>
</head>

<body>

Joystick Controls.
<hr>
<div id="status1" style="color: red;">Joystick 1</div>
<div id="status2" style="color: blue;">Joystick 2</div>

<hr>
<div style="border: 1px solid red; width: 128px; position: absolute; left:10px; top:150px;">
<img src="images/joystick-base.png"/>
<div id="stick1" style="position: absolute; left:32px; top:32px;">
<img src="images/joystick-red.png"/>
</div>
</div>

<div style="border: 1px solid blue; width: 128px; position: absolute; left:210px; top:150px;">
<img src="images/joystick-base.png"/>
<div id="stick2" style="position: absolute; left:32px; top:32px;">
<img src="images/joystick-blue.png"/>
</div>
</div>

<script>



let joystick1 = new Joystick("stick1", 64, 8);
let joystick2 = new Joystick("stick2", 64, 8);

function update()
{
document.getElementById("status1").innerText = "Joystick 1: " + JSON.stringify(joystick1.value);
document.getElementById("status2").innerText = "Joystick 2: " + JSON.stringify(joystick2.value);
}

function loop()
{
requestAnimationFrame(loop);
update();
}

loop();

</script>

</body>
</html>
161 changes: 96 additions & 65 deletions js/extended-wasd-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,15 @@ AFRAME.registerComponent('extended-wasd-controls', {
turnEnabled: {type: 'boolean', default: true},
lookEnabled: {type: 'boolean', default: true},

// if you are attaching extended-wasd-controls to a camera
// that also has the look-controls component,
// set this to true to use look-controls from rotation to calculate forward/right vectors.
// For responsive magic window effect on tablets, set turnEnabled/lookEnabled to false also.
coordinateLookControls: {type: 'boolean', default: false},

// consider setting to maxLook to false when working with look controls;
// complicated to handle the combination accurately
maxLookEnabled: {type: 'boolean', default: true},
maxLookAngle: {type: 'number', default: 60},
maxLookAngle: {type: 'number', default: 60},

moveSpeed: {type: 'number', default: 1}, // A-Frame units/second
turnSpeed: {type: 'number', default: 30}, // degrees/second
lookSpeed: {type: 'number', default: 30} // degrees/second
lookSpeed: {type: 'number', default: 30}, // degrees/second

// use keyboard or other (e.g. joystick) to activate these controls
inputType: {type: 'string', default: "keyboard"}
},

convertKeyName: function(keyName)
Expand Down Expand Up @@ -94,8 +89,18 @@ AFRAME.registerComponent('extended-wasd-controls', {

// movement-related data

this.forwardVector = new THREE.Vector3(0,0,-1);
this.rightVector = new THREE.Vector3(1,0,0);
this.moveVector = new THREE.Vector3(0,0,0);
this.movePercent = new THREE.Vector3(0,0,0);
// z = forward/backward
// x = left/right
// y = up/down

this.rotateVector = new THREE.Vector2(0,0);
this.rotatePercent = new THREE.Vector2(0,0);
// y = turn angle
// x = look angle

// used as reference vector when turning
this.upVector = new THREE.Vector3(0,1,0);

// current rotation amounts
Expand All @@ -121,34 +126,60 @@ AFRAME.registerComponent('extended-wasd-controls', {
// rotations

// reset values
this.upVector.set(0,1,0);

let totalTurnAngle = 0;
let totalLookAngle = 0;

if ( this.lookControls ) // take into account lookControls, if they exist
// look-controls and extended-wasd-controls are compatible
// with desktop/mouse combo but not for tablet/gyroscope combo ("magic window" effect)
// (at least not with this code)
// thus, look/turn automatically disabled when look-controls present

console.log("rev. 6");

if ( this.lookControls ) // take into account look-controls, if they exist
{
totalTurnAngle += this.lookControls.yawObject.rotation.y;
totalLookAngle += this.lookControls.pitchObject.rotation.x;
// this code is only useful when trying to combine
// look-controls with extended-wasd rotation
// totalTurnAngle += this.lookControls.yawObject.rotation.y;
// totalLookAngle += this.lookControls.pitchObject.rotation.x;
}

if ( this.data.lookEnabled )
else
{
if (this.isKeyPressed(this.data.lookUpKey))
this.lookAngle += lookAmount;

if (this.isKeyPressed(this.data.lookDownKey))
this.lookAngle -= lookAmount;
if (this.data.inputType == "keyboard")
{
// need to reset rotatePercent values
// when querying which keys are currently pressed
this.rotatePercent.set(0,0);

if (this.isKeyPressed(this.data.lookUpKey))
this.rotatePercent.x += 1;
if (this.isKeyPressed(this.data.lookDownKey))
this.rotatePercent.x -= 1;

if (this.isKeyPressed(this.data.turnLeftKey))
this.rotatePercent.y += 1;
if (this.isKeyPressed(this.data.turnRightKey))
this.rotatePercent.y -= 1;

// center on horizon
if (this.isKeyPressed(this.data.lookUpKey) && this.isKeyPressed(this.data.lookDownKey))
this.lookAngle *= 0.90;
}
else // other, e.g. "joystick"
{
// assume this.rotatePercent values have been set/reset elsewhere (outside of this function)
}

totalLookAngle += this.lookAngle;
if ( this.data.lookEnabled )
{
this.lookAngle += this.rotatePercent.x * lookAmount;
this.el.object3D.rotation.x = this.lookAngle;
}

// look towards horizon when both are pressed;
// does not work well when used with look-controls
if ( !this.lookControls )
if ( this.data.turnEnabled )
{
if (this.isKeyPressed(this.data.lookUpKey)
&& this.isKeyPressed(this.data.lookDownKey))
this.lookAngle *= 0.90;
this.turnAngle += this.rotatePercent.y * turnAmount;
this.el.object3D.rotation.y = this.turnAngle;
}

// enforce bounds on look angle (avoid upside-down perspective)
Expand All @@ -159,54 +190,54 @@ AFRAME.registerComponent('extended-wasd-controls', {
if (this.lookAngle < -maxLookAngle)
this.lookAngle = -maxLookAngle;
}

this.el.object3D.rotation.set(totalLookAngle, 0, 0);
}

if (this.data.turnEnabled)
{
if (this.isKeyPressed(this.data.turnLeftKey))
this.turnAngle += turnAmount;

if (this.isKeyPressed(this.data.turnRightKey))
this.turnAngle -= turnAmount;

totalTurnAngle += this.turnAngle;

this.el.object3D.rotateOnWorldAxis(this.upVector, totalTurnAngle);
}

// translations

// this only works when rotation order = "YXZ"
let finalTurnAngle = this.el.object3D.rotation.y;

let c = Math.cos(finalTurnAngle);
let s = Math.sin(finalTurnAngle);

this.forwardVector.set( -s, 0, -c ).multiplyScalar( moveAmount );
this.rightVector.set( c, 0, -s ).multiplyScalar( moveAmount );
this.upVector.set( 0, 1, 0 ).multiplyScalar( moveAmount );

if (this.isKeyPressed(this.data.moveForwardKey))
this.el.object3D.position.add( this.forwardVector );

if (this.isKeyPressed(this.data.moveLeftKey))
this.el.object3D.position.sub( this.rightVector );
if (this.data.inputType == "keyboard")
{
// need to reset movePercent values
// when querying which keys are currently pressed
this.movePercent.set(0,0,0)

if (this.isKeyPressed(this.data.moveBackwardKey))
this.el.object3D.position.sub( this.forwardVector );
if (this.isKeyPressed(this.data.moveForwardKey))
this.movePercent.z += 1;
if (this.isKeyPressed(this.data.moveBackwardKey))
this.movePercent.z -= 1;

if (this.isKeyPressed(this.data.moveRightKey))
this.el.object3D.position.add( this.rightVector );
if (this.isKeyPressed(this.data.moveRightKey))
this.movePercent.x += 1;
if (this.isKeyPressed(this.data.moveLeftKey))
this.movePercent.x -= 1;

if (this.data.flyEnabled)
if ( this.data.flyEnabled )
{
if (this.isKeyPressed(this.data.moveUpKey))
this.movePercent.y += 1;
if (this.isKeyPressed(this.data.moveDownKey))
this.movePercent.y -= 1;
}
}
else // other, e.g. "joystick"
{
if (this.isKeyPressed(this.data.moveUpKey))
this.el.object3D.position.add( this.upVector );

if (this.isKeyPressed(this.data.moveDownKey))
this.el.object3D.position.sub( this.upVector );
// assume this.movePercent values have been set/reset elsewhere (outside of this function)
}

// forward(z) direction: [ -s, 0, -c ]
// right(x) direction: [ c, 0, -s ]
// up(y) direction: [ 0, 1, 0 ]
// multiply each by (maximum) movement amount and percentages (how much to move in that direction)

this.moveVector.set( -s * this.movePercent.z + c * this.movePercent.x,
1 * this.movePercent.y,
-c * this.movePercent.z - s * this.movePercent.x ).multiplyScalar( moveAmount );

this.el.object3D.position.add( this.moveVector );
}
});
Loading

0 comments on commit ca06ab8

Please sign in to comment.