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 1104117 of Unconventional controls

  • Revision slug: Games/Techniques/Input_controls/Other
  • Revision title: Implementing input controls the unconventional ways
  • Revision id: 1104117
  • Created:
  • Creator: end3r
  • Is current revision? No
  • Comment

Revision Content

Having different control mechanisms in your game help reach broader audience. Implementing mobile controls along with desktop controls is recommended, and gamepad controls add that extra experience. Imagine going even further - in this article we will explore various, more or less conventional, ways to control your web game.

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. New smart TVs can handle HTML5 games, because everything having a built-in browser can be used as a gaming platform. Smart TVs are shipped with remote controls - let's see if you can build and adjust your game to be played using a remote.

The earliest demo of Captain Rogers: Battle at Andromeda was adjusted to work on a huge TV. The funny thing was, the first Captain Rogers: 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 Building games for Firefox OS TV Hacks post.

---IMG_MENU_OR_OTHER_WITH_KEY_INFO---

Using remote to control the game ended up being surprisingly easy, because the events fired by the controller are emulating the 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's working out of the box. The cursors are the four directional arrow keys on the keyboard, and have exactly the same key codes on the remote. How do you know the codes for other remote keys? You can check them by printing it 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.

It's great for virtual interfaces, but can also be used for a casual 2D gaming. It would be very difficult to do everything with only your hands, but it's totally doable for the gameplay - steering the ship and shooting the bullets.

There's a good Hello World and Getting Started JavaScript tutorials 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 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 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 to 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 on Using the Web Speech API which covers the basics on the topic. The demo include a grammar - list of recognized words the speech recognition script can use.

Doppler effect

There's a very interesting article on Motion sensing using the doppler effect, which include mixing 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!

Using a small library created by Daniel Rapp can be as simple as calculating the difference:

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 me 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 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.

MaKey MaKey

Ultimately, if you want to go 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 - those are only a few out of many you can try yourself. Feel free to add anything you think would fit here. And remember: have fun making games!

Revision Source

<p class="summary">Having different control mechanisms in your game help reach broader audience. Implementing mobile controls along with desktop controls is recommended, and gamepad controls add that extra experience. Imagine going even further - in this article we will explore various, more or less conventional, ways to control your web game.</p>

<h2>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. New smart TVs can handle HTML5 games, because everything having a built-in browser can be used as a gaming platform. Smart TVs are shipped with remote controls - let's see if you can build and adjust your game to be played using a remote.</p>

<p>The earliest demo of Captain Rogers: Battle at Andromeda was adjusted to work on a huge TV. The funny thing was, the first Captain Rogers: 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 <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 remote to control the game ended up being surprisingly easy, because the events fired by the controller are emulating the 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's working out of the box. The cursors are the four directional arrow keys on the keyboard, and have exactly the same key codes on the remote. How do you know the codes for other remote keys? You can check them by printing it 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>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>It's great for virtual interfaces, but can also be used for a casual 2D gaming. It would be very difficult to do everything with only your hands, but it's totally doable for the gameplay - steering the ship and shooting the bullets.</p>

<p>There's a 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 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 <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>Voice</h2>

<p>Instead of using your hands to control the game, maybe you could do the same 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 to 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 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 include a grammar - list of recognized words the speech recognition script can use.</p>

<h2>Doppler effect</h2>

<p>There's a very interesting article on <a href="https://danielrapp.github.io/doppler/">Motion sensing using the doppler effect</a>, which include mixing 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>Using <a href="https://github.com/DanielRapp/doppler">a small library</a> created by Daniel Rapp can be as simple as calculating the difference:</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 me enough to move the ship on the screen up and down if implemented correctly.</p>

<h2>Proximity API</h2>

<p>Another interesting idea is to use the built-in proximity sensors 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>

<h2>MaKey MaKey</h2>

<p>Ultimately, if you want to go 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>Summary</h2>

<p>I hope you liked the experiments - those are only a few out of many you can try yourself. Feel free to add anything you think would fit here. And remember: have fun making games!</p>
Revert to this revision