Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1109661 of Unconventional controls

  • Revision slug: Games/Techniques/Control_mechanisms/Other
  • Revision title: Unconventional controls
  • Revision id: 1109661
  • Created:
  • Creator: chrisdavidmills
  • Is current revision? No
  • Comment

Revision Content

{{PreviousMenu("Games/Techniques/Control_mechanisms/Desktop_with_gamepad", "Games/Techniques/Control_mechanisms")}}

Having different control mechanisms in your game helps reach broader audiences. Implementing mobile and desktop controls is recommended is a must, and gamepad controls add that extra experience. But imagine going even further — in this article we will explore various unconventional ways to control your web game, some more unconventional than others.

TV remote

Playing games on a TV screen doesn't always have to be done through consoles. There's already a Gamepad API working on the desktop computers, so we can imitate the experience, but we can go even further. Modern smart TVs can handle HTML5 games, because they have a built-in browser that can be used as a gaming platform. Smart TVs are shipped with remote controls, which can be used to control your games if you know how.

The earliest demo of Captain Rogers: Battle at Andromeda was adjusted to work on a huge TV. Interestingly enough, the first Captain Rogers game (Asteroid Belt of Sirius) was optimized for low-end, small-screen, cheap smartphones running Firefox OS, so you can see the difference three years can make — you can read the whole story in our Building games for Firefox OS TV Hacks post.

---IMG_MENU_OR_OTHER_WITH_KEY_INFO---

Using a TV remote to control the game ended up being surprisingly easy, because the events fired by the controller are emulating conventional keyboard keys. Captain Rogers had the keyboard controls implemented already:

this.cursors = this.input.keyboard.createCursorKeys();
//...
if(this.cursors.right.isDown) {
    // move player right
}

It works out of the box. The cursors are the four directional arrow keys on the keyboard, and these have exactly the same key codes as the arrow keys on the remote. How do you know the codes for the other remote keys? You can check them by printing the responses out in the console:

window.addEventListener("keydown", function(event) {
    console.log(event.keyCode);
}, this);

Every key pressed on the remote will show its key code in the console. You can also check this handy cheat sheet if you're working with Panasonic TVs running Firefox OS:

---IMG_REMOTE_KEY_MAPPING---

You can add moving between states, starting a new game, controlling the ship and blowing stuff up, pausing and restarting the game. All that is needed is checking for key presses:

window.addEventListener("keydown", function(event) {
    switch(event.keyCode) {
        case 8: {
            // pause the game
            break;
        }
        case 588: {
            // detonate bomb
            break;
        }
        // ...
    }
}, this);

You can see it in action by watching this video.

Leap Motion

Have you ever thought about controlling a game only with your hands? It's possible with Leap Motion, an immersive controller for games and apps.

It's more and more popular due to very good integration with VR headsets — demoing Rainbow Membrane on an Oculus Rift with Leap Motion attached to it was voted one of the best WebVR experiences by JavaScript developers visiting demo booths at conferences around the world.

As well as being great for virtual interfaces, it can also be used for a casual 2D gaming experirence. It would be very difficult to do everything with only your hands, but it's totally doable for the simple Captain Roger's gameplay — steering the ship and shooting the bullets.

There's good Hello World and Getting Started JavaScript tutorials available on the Leap Motion documentation pages, which will get you through the basics. You can also check the tutorial about using Leap Motion plugin for Kiwi.js, or the case study of building a web game with Leap Motion and Pixi.js. Be sure to visit the LeapJS repository on GitHub to learn about the JavaScript client for the Leap Motion controller and read the documentation there.

If all else fails, there's also a gallery of working examples which you can check yourself.

Voice

Instead of using your hands to control the game, maybe you could do the same thing a little bit differently? Think of a little experiment: shooting by shouting. You could develop a special version of the game where shooting is done by shouting into the microphone. It sounds crazy, and won't make much sense in a long run, but it's an interesting approach nonetheless.

You can go even further and try to implement voice commands with the Web Speech API. Instead of clicking the button dropping the bomb you could say 'detonate' and it would work without touching anything. It would work best in a 3D environment where on-screen display is a tricky topic, so having voice commands would help a lot, but it's still an option in simple 2D games — if not for the movement, then at least for all the other actions.

There's an interesting article available on Using the Web Speech API which covers the basics on the topic. The demo includes a grammar list of recognized words the speech recognition script can use.

Doppler effect

There's a very interesting article available on Motion sensing using the doppler effect, which includes mixing the two previous approaches: waving your hand and using the microphone. This time it's about detecting sound waves bouncing off objects and returning to the microphone.

---IMG_DOPPLER_EFFECT---

If the frequency of the bounced sound is shifted from the original one, then we can detect that the movement of that object occured. That way we can detect a hand movement by using only a built-in microphone!

This can be accomplished using a small library created by Daniel Rapp — it can be as simple as calculating the difference between two frequencies:

doppler.init(function(bandwidth) {
    var diff = bandwidth.left - bandwidth.right;
});

The diff would be the difference between the initial position of the hand and the final one.

It won't give us the full flexibility of using a Gamepad, or even Leap Motion, but it's definitely an interesting, unconventional alternative. You can use it to scroll a page hands-free, or play theremin, but it should also be enough to move the ship on the screen up and down if implemented correctly.

Proximity API

Another interesting idea is to use the built-in proximity sensors of your hardware to detect how far an object, for example a hand, is from the given sensor. It could work similar to the doppler effect in terms of manipulating the player's ship on the screen by moving your hand closer or further from the device.

---IMG_PROXIMITY---

An event listener for device proximity would look like this:

window.addEventListener('deviceproximity', function(event) {
    var min = event.min;
    var max = event.max;
    var proximity = event.value;
});

The min and max values are the minimum and the maximum distances respectively between which the sensor can detect the exact proximity value. All three are calculated in centimetres.

Note: See the {{domxref("DeviceProximityEvent")}} reference page for more details.

MaKey MaKey

If you want to go completely bananas you can use MaKey MaKey, a board that can turn anything into a controller — it's all about connecting real-world, conductive objects to a computer and using them as touch interfaces.

---IMG_MAKEYMAKEY_BANANAS---

Check out the banana piano video, and be sure to visit the quick start guide for all the needed info.

There's even a Cylon.js-supported Makey Button functionality inspired by the MaKey MaKey board, so you can use this widely popular robotics framework for your experiments with Arduino or Raspberry Pi. Connecting the boards and using them may look like this:

var Cylon = require('cylon');
Cylon.robot({
  connections: {
    arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' }
  },
  devices: {
    makey: { driver: 'makey-button', pin: 2 }
  },
  work: function(my) {
    my.makey.on('push', function() {
      console.log("Button pushed!");
    });
  }
}).start();

As the description says: this GPIO driver allows you to connect a 10 MOhm resistor to a digital pin on your Arduino or Raspberry Pi to control your robots with bananas, clay, or drawable circuitry.

Summary

I hope you liked the experiments — if you have any others that you think might interest other people, feel free to add details of them here.

And remember: have fun making games!

{{PreviousMenu("Games/Techniques/Control_mechanisms/Desktop_with_gamepad", "Games/Techniques/Control_mechanisms")}}

Revision Source

<p>{{PreviousMenu("Games/Techniques/Control_mechanisms/Desktop_with_gamepad", "Games/Techniques/Control_mechanisms")}}</p>

<p class="summary">Having different control mechanisms in your game helps reach broader audiences. Implementing mobile and desktop controls is recommended is a must, and gamepad controls add that extra experience. But imagine going even further — in this article we will explore various unconventional ways to control your web game, some more unconventional than others.</p>

<h2 id="TV_remote">TV remote</h2>

<p>Playing games on a TV screen doesn't always have to be done through consoles. There's already a Gamepad API working on the desktop computers, so we can imitate the experience, but we can go even further. Modern smart TVs can handle HTML5 games, because they have a built-in browser that can be used as a gaming platform. Smart TVs are shipped with remote controls, which can be used to control your games if you know how.</p>

<p>The earliest demo of <a class="external external-icon" href="https://rogers2.enclavegames.com/demo/">Captain Rogers: Battle at Andromeda</a> was adjusted to work on a huge TV. Interestingly enough, the first Captain Rogers game (Asteroid Belt of Sirius) was optimized for low-end, small-screen, cheap smartphones running Firefox OS, so you can see the difference three years can make — you can read the whole story in our <a href="https://hacks.mozilla.org/2016/01/building-games-for-firefox-os-tv/">Building games for Firefox OS TV</a> Hacks post.</p>

<p>---IMG_MENU_OR_OTHER_WITH_KEY_INFO---</p>

<p>Using a TV remote to control the game ended up being surprisingly easy, because the events fired by the controller are emulating conventional keyboard keys. Captain Rogers had the keyboard controls implemented already:</p>

<pre>
this.cursors = this.input.keyboard.createCursorKeys();
//...
if(this.cursors.right.isDown) {
    // move player right
}</pre>

<p>It works out of the box. The cursors are the four directional arrow keys on the keyboard, and these have exactly the same key codes as the arrow keys on the remote. How do you know the codes for the other remote keys? You can check them by printing the responses out in the console:</p>

<pre>
window.addEventListener("keydown", function(event) {
    console.log(event.keyCode);
}, this);</pre>

<p>Every key pressed on the remote will show its key code in the console. You can also check this handy cheat sheet if you're working with Panasonic TVs running Firefox OS:</p>

<p>---IMG_REMOTE_KEY_MAPPING---</p>

<p>You can add moving between states, starting a new game, controlling the ship and blowing stuff up, pausing and restarting the game. All that is needed is checking for key presses:</p>

<pre>
window.addEventListener("keydown", function(event) {
    switch(event.keyCode) {
        case 8: {
            // pause the game
            break;
        }
        case 588: {
            // detonate bomb
            break;
        }
        // ...
    }
}, this);</pre>

<p>You can see it in action by watching <a href="https://www.youtube.com/watch?v=Bh11sP0bcTY">this video</a>.</p>

<h2 id="Leap_Motion">Leap Motion</h2>

<p>Have you ever thought about controlling a game only with your hands? It's possible with <a href="https://www.leapmotion.com/">Leap Motion</a>, an immersive controller for games and apps.</p>

<p>It's more and more popular due to very good integration with VR headsets — demoing <a href="https://mozvr.com/webvr-demos/demos/rainbowmembrane/">Rainbow Membrane</a> on an Oculus Rift with Leap Motion attached to it was voted one of the best WebVR experiences by JavaScript developers visiting demo booths at conferences around the world.</p>

<p>As well as being great for virtual interfaces, it can also be used for a casual 2D gaming experirence. It would be very difficult to do everything with only your hands, but it's totally doable for the simple Captain Roger's gameplay — steering the ship and shooting the bullets.</p>

<p>There's good <a href="https://developer.leapmotion.com/documentation/javascript/devguide/Sample_Tutorial.html">Hello World</a> and <a href="https://developer.leapmotion.com/getting-started/javascript">Getting Started</a> JavaScript tutorials available on the Leap Motion documentation pages, which will get you through the basics. You can also check the tutorial about <a href="https://gamedevelopment.tutsplus.com/tutorials/add-motion-control-to-a-kiwijs-game-with-the-leap-motion-controller--cms-20455">using Leap Motion plugin for Kiwi.js</a>, or the case study of <a href="https://arstechnica.com/business/2014/04/building-a-gesture-controlled-web-game-with-leap-motion/">building a web game with Leap Motion and Pixi.js</a>. Be sure to visit the <a href="https://github.com/leapmotion/leapjs">LeapJS repository on GitHub</a> to learn about the JavaScript client for the Leap Motion controller and read the documentation there.</p>

<p>If all else fails, there's also a <a href="https://developer.leapmotion.com/gallery/category/javascript">gallery of working examples</a> which you can check yourself.</p>

<h2 id="Voice">Voice</h2>

<p>Instead of using your hands to control the game, maybe you could do the same thing a little bit differently? Think of a little experiment: shooting by shouting. You could develop a special version of the game where shooting is done by shouting into the microphone. It sounds crazy, and won't make much sense in a long run, but it's an interesting approach nonetheless.</p>

<p>You can go even further and try to implement voice commands with the Web Speech API. Instead of clicking the button dropping the bomb you could say <em>'detonate'</em> and it would work without touching anything. It would work best in a 3D environment where on-screen display is a tricky topic, so having voice commands would help a lot, but it's still an option in simple 2D games — if not for the movement, then at least for all the other actions.</p>

<p>There's an interesting article available on <a href="/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API">Using the Web Speech API</a> which covers the basics on the topic. The demo includes a grammar list of recognized words the speech recognition script can use.</p>

<h2 id="Doppler_effect">Doppler effect</h2>

<p>There's a very interesting article available on <a href="https://danielrapp.github.io/doppler/">Motion sensing using the doppler effect</a>, which includes mixing the two previous approaches: waving your hand and using the microphone. This time it's about detecting sound waves bouncing off objects and returning to the microphone.</p>

<p>---IMG_DOPPLER_EFFECT---</p>

<p>If the frequency of the bounced sound is shifted from the original one, then we can detect that the movement of that object occured. That way we can detect a hand movement by using only a built-in microphone!</p>

<p>This can be accomplished using <a href="https://github.com/DanielRapp/doppler">a small library</a> created by Daniel Rapp — it can be as simple as calculating the difference between two frequencies:</p>

<pre>
doppler.init(function(bandwidth) {
    var diff = bandwidth.left - bandwidth.right;
});</pre>

<p>The <code>diff</code> would be the difference between the initial position of the hand and the final one.</p>

<p>It won't give us the full flexibility of using a Gamepad, or even Leap Motion, but it's definitely an interesting, unconventional alternative. You can use it to scroll a page hands-free, or play theremin, but it should also be enough to move the ship on the screen up and down if implemented correctly.</p>

<h2 id="Proximity_API">Proximity API</h2>

<p>Another interesting idea is to use the built-in proximity sensors of your hardware to detect how far an object, for example a hand, is from the given sensor. It could work similar to the doppler effect in terms of manipulating the player's ship on the screen by moving your hand closer or further from the device.</p>

<p>---IMG_PROXIMITY---</p>

<p>An event listener for device proximity would look like this:</p>

<pre>
window.addEventListener('deviceproximity', function(event) {
    var min = event.min;
    var max = event.max;
    var proximity = event.value;
});</pre>

<p>The <code>min</code> and <code>max</code> values are the minimum and the maximum distances respectively between which the sensor can detect the exact <code>proximity</code> value. All three are calculated in centimetres.</p>

<div class="note">
<p><strong>Note</strong>: See the {{domxref("DeviceProximityEvent")}} reference page for more details.</p>
</div>

<h2 id="MaKey_MaKey">MaKey MaKey</h2>

<p>If you want to go completely bananas you can use <a href="https://makeymakey.com/">MaKey MaKey</a>, a board that can turn anything into a controller — it's all about connecting real-world, conductive objects to a computer and using them as touch interfaces.</p>

<p>---IMG_MAKEYMAKEY_BANANAS---</p>

<p>Check out the <a href="https://www.youtube.com/watch?v=_DWQ6ce2Ags">banana piano video</a>, and be sure to visit the <a href="https://learn.sparkfun.com/tutorials/makey-makey-quickstart-guide">quick start guide</a> for all the needed info.</p>

<p>There's even a <a href="https://cylonjs.com/documentation/drivers/makey-button/">Cylon.js-supported Makey Button functionality</a> inspired by the MaKey MaKey board, so you can use this widely popular robotics framework for your experiments with Arduino or Raspberry Pi. Connecting the boards and using them may look like this:</p>

<pre>
var Cylon = require('cylon');
Cylon.robot({
  connections: {
    arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' }
  },
  devices: {
    makey: { driver: 'makey-button', pin: 2 }
  },
  work: function(my) {
    my.makey.on('push', function() {
      console.log("Button pushed!");
    });
  }
}).start();</pre>

<p>As the description says: this GPIO driver allows you to connect a 10 MOhm resistor to a digital pin on your Arduino or Raspberry Pi to control your robots with bananas, clay, or drawable circuitry.</p>

<h2 id="Summary">Summary</h2>

<p>I hope you liked the experiments — if you have any others that you think might interest other people, feel free to add details of them here.</p>

<p>And remember: have fun making games!</p>

<p>{{PreviousMenu("Games/Techniques/Control_mechanisms/Desktop_with_gamepad", "Games/Techniques/Control_mechanisms")}}</p>
Revert to this revision