Mobile Zone is brought to you in partnership with:

David Catuhe is a Microsoft HTML5 Evangelist based in Paris, France. He does much of his research on Windows 8, Kinect, and the various HTML5 standards and JS libraries. David is a DZone MVB and is not an employee of DZone and has posted 23 posts at DZone. You can read more from them at their website. View Full User Profile

Understanding DeviceOrientation Events: A 3D Game with Babylon.js

10.13.2013
| 3000 views |
  • submit to reddit

Internet Explorer 11 adds support for some cool new DOM events: the DeviceOrientation events. These events provide information about the physical orientation and motion of the current hardware.

The W3C has published a specification for these events: http://www.w3.org/TR/orientation-event/

During this article I will show you how to use these events within a small 3D game featuring an “Amiga” ball Sourire.

The final result will look like this.

Wanna try it? Just go there (you can use device orientation or the cursors keys).

DeviceOrientation Events and Babylon.js

Before looking in detail at the DeviceOrientation specification, you can have a look at this video showing the usage of device orientation within a babylon.js scene. And as you can see, it ROCKS!

How DeviceOrientation Events Work

There are two types of data exposed by the DeviceOrientation events:

  • Orientation (deviceorientation): This value defines the orientation of the physical device in relation to a coordinate system centered on Earth. It is expressed in degrees. Three coordinates are provided:
    • alpha: rotation around z axis
    • beta: rotation around x axis
    • gamma: rotation around y axis

The axis are defined using a right handed convention:

image

To understand these values, let’s start with the device in your hands:

image

The alpha orientation changes when you move the device around the z axis:

image

The beta orientation changes when you move the device around the x axis:

image

Finally, the gamma orientation changes when you move the device around the y axis:

image

  • Motion (devicemotion): This value defined the acceleration along each axis (x, y, z). The values are expressed in m/s² and can include (or not) the effect of the gravity). This event can also provide the rate of rotation (in deg/s) around each axis.

For more in-depth information, please have a look to the MSDN documentation.

The orientation is retrieved using the “deviceorientation” event fired on the window object:

window.addEventListener("deviceorientation", moveBall);
function moveBall(evt) {
    if (evt.alpha < 5 || evt.alpha > 355) {
        ball.position.z += 0.1;

    }
}

The motion is retrieved using the “devicemotion” event fired on the window object:

window.addEventListener("devicemotion", detectShake);
function detectShake(evt) {
    var accl = evt.acceleration;
    if (accl.x > 1.5 || accl.y > 1.5 || accl.z > 1.5) {
        // Tilt :)
        onLose();
    }
}

The first obvious usage of these events is to control a game. You can also use them for gesture recognition or for detecting the orientation of the user to use accordingly with a map.

Creating the Ball Game

The game that we will create is a simple ball game where you must control a ball and make it move to specific points in order to gain points:

image

The particle system in the upper right corner defines the place where you must move the ball. Once the ball is near the good place, you will earn a point.

Every time you earn a point, the ball speed will be increased and the playground will rotate to increase difficulty Sourire.

So, first of all, you need to create a simple HTML file with a reference to babylon.js (incredible!):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Device orientation - ball game</title>
    <link href="index.css" rel="stylesheet" />
    <script src="babylon.js"></script>
</head>
<body>
    <canvas id="renderCanvas"></canvas>   
    <div id="score">Score: 0</div>
    <div id="speed">Speed: 1</div>
    <div id="gameOver" class="hidden">
        <div id="gameOverText">Game Over</div>
    </div>
    <script src="index.js"></script>
</body>
</html>

Then inside index.js, we can create the 3D environment required by our game. The first thing to do is to create the engine and the scene;

var canvas = document.getElementById("renderCanvas");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

if (BABYLON.Engine.isSupported()) {

    var engine = new BABYLON.Engine(canvas, true);
    var scene = new BABYLON.Scene(engine);
    var light = new BABYLON.DirectionalLight("light", new BABYLON.Vector3(2, -10, 5), scene);
    var camera = new BABYLON.ArcRotateCamera("camera", 3 * Math.PI / 2.0, Math.PI / 4.0, 20.0, new BABYLON.Vector3(0, 0, 0), scene);

    scene.activeCamera = camera;

You will also need a render loop to ensure frames are drawn to the canvas:

engine.runRenderLoop(function () {
    scene.render();
    
    if (!started) {
        return;
    }

});

For now, the screen is a bit empty:

image

Then we can create the starfield to get a cool background. It will be created as a particle system:

// Starfield
var starfield = new BABYLON.ParticleSystem("particles", 4000, scene);
starfield.particleTexture = new BABYLON.Texture("star.png", scene);
starfield.minAngularSpeed = -4.5;
starfield.maxAngularSpeed = 4.5;
starfield.minSize = 0.5;
starfield.maxSize = 1.0;
starfield.minLifeTime = 0.5;
starfield.maxLifeTime = 2.0;
starfield.minEmitPower = 0.5;
starfield.maxEmitPower = 1.0;
starfield.emitRate = 600;
starfield.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
starfield.minEmitBox = new BABYLON.Vector3(-25, 0, -25);
starfield.maxEmitBox = new BABYLON.Vector3(25, 0, 25);
starfield.direction1 = new BABYLON.Vector3(0, 1, 0);
starfield.direction2 = new BABYLON.Vector3(0, 1, 0);
starfield.color1 = new BABYLON.Color4(0, 0, 0, 1);
starfield.color2 = new BABYLON.Color4(1, 1, 1, 1);
starfield.gravity = new BABYLON.Vector3(0, 5, 0);
starfield.emitter = new BABYLON.Vector3(0, -2, 0);
starfield.start();

For more information on particle system, you can go here.

Published at DZone with permission of David Catuhe, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)