Making an interactive hoverboard game using JavaScript and web sockets.
Tags: javascript, iot, webdev, creativecoding
Published: 2019-07-02 21:30:40

---
title: Making an interactive hoverboard game using JavaScript and web sockets.
published: true
description: This tutorial explains how to use web sockets and Three.js to build an interactive game.
tags: javascript, iot, web development, creative coding
cover_image: https://thepracticaldev.s3.amazonaws.com/i/7v2dpz9p27sp96n3qz4m.png
---


## Back story

*The original version of this project was built using a [Daydream controller](https://vr.google.com/intl/en_au/daydream/smartphonevr/).*

***To make it accessible to more people, I've spent some time changing it so you can use your phone instead.***

*However, FIY, you can also build your own controller using something like an Arduino, accelerometer and bluetooth module if you feel like it!* 😃

*For the 1st version of this project, I used Web Bluetooth to connect the Daydream controller directly to the browser and I was hoping the code would stay quite similar, but I realised phones cannot connect to laptops using the Web Bluetooth API. Both phone and laptop can only be "central" devices, and not "peripheral", so I've had to change this demo to use Web Sockets instead to communicate between the phone and the laptop.*


{% youtube d3QRNH_jNOI %}


---

## How does it work?

This version of the experiment works by having the main webpage open on your computer and another webpage open on your mobile phone to get the accelerometer data.

Using the [DeviceOrientation Web API](https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation), the orientation of the phone is detected and sent to the browser on your laptop via WebSockets.

By placing your phone on a skateboard, it can become a controller. You can use the orientation data to apply it to the 3D environment and interact with the game as if you were on a hoverboard.

---

## What this tutorial is about

I'm not gonna go through the whole code as I don't think going through it line by line will be very beneficial. Instead, i'm going to explain the core parts of the prototype.

If you want to skip all this and just check out the **[Github repo](https://github.com/charliegerard/hvbrd-sockets)**, the **[CodeSandbox](https://codesandbox.io/s/hvbrd-sockets-ln0mi)** or try the **[live demo](https://bit.ly/hvbrd)**, feel free.

---

## Material needed:

* A modern mobile phone (any phone that has an accelerometer built-in).
* A computer.
* A projector *(optional)*.

### Tech stack:

* HTML
* CSS
* JavaScript (Vanilla JS, no framework knowledge needed!).
* DeviceOrientation Web API
* Node.js with Socket.io

---

## Step 1: Setup the Node.js server and web sockets

To get started, we need to set up a server to serve our files, expose routes and set up socket.io.


![Express.js server](https://thepracticaldev.s3.amazonaws.com/i/fnv29xqn9vsfvxt5mxmf.png)

In the code sample above, we require some modules, start an [Express](https://expressjs.com/) server and indicate the path and routes to serve our files.

We also set up a basic socket.io connection that will wait for the communication between the server and front-end to be established. Once connected, socket.io will wait for certain messages from the front-end.

The 1st message should be received when the user visits the mobile page so we can confirm that they are ready to interact with the game. When this message is received, we emit one that the page on desktop will be listening to so we can start the game.

The 2nd message will be received when the mobile starts streaming orientation data. This message will emit an event to the desktop browser with the data so it can be applied to the hoverboard.

Now that our server is set up, let's work on the front-end.

---

## Step 2: Getting and streaming orientation data

Using the [DeviceOrientation Web API](https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation), we're able to get orientation data from the mobile phone.

To set this up and send it back to the server, we need code that looks like this:

![Streaming orientation data](https://thepracticaldev.s3.amazonaws.com/i/fwrwbgsprivqiaf9f6vq.png)

Here, we're instantiating socket.io and when the page loads, we're sending a first message to the server to indicate that the mobile page has been visited.

Then, we have an event listener that checks for `deviceorientation` events. On change, we call the `handleOrientation` function that sends another event to the server with the data on a certain axis. This data represents the change of position from left to right as you tilt the skateboard.

Now that the page on mobile is sending orientation data to the server, let's see how the desktop page is listening to it.

---

## Step 3: Listen to the orientation data in the game

To be able to use the orientation data from the phone on the laptop, we need to be listening to the message sent by the server.


![Getting orientation data](https://thepracticaldev.s3.amazonaws.com/i/6e3ekf5indnfy6e5n331.png)


Again, we instantiate socket.io, and when we receive the message `mobile orientation` from the server, we're able to use the tilt data in our game.

In the code sample above, I also added a `previousValue` variable so we would only be using the orientation data if it is different from the one previously received.

Now that we set up a basic communication between the server and front-ends, as well as got the orientation data from the phone, we can start building the game around it using [Three.js](https://threejs.org/).

---

## Step 4: Setting up the game

### Loading the libraries

The 3D environment built in this project is using Three.js. To start using it as well as a few add-ons, we need to include them in our HTML.

![scripts](https://thepracticaldev.s3.amazonaws.com/i/52o61t3oqxrlur0n3z3c.png)

Not all of these are needed if you want to create a basic game. The files `CopyShader`, `DigitalGlitch`, `EffectComposer`, `ShaderPass` and `GlitchPass` are only used for the effect I added on collision with an obstacle.

The main resources needed here are the Three.js library, the `noiseSimplex` script to generate the plane and the `OBJ` and `MTL` loaders to load the 3D assets used for the hoverboard and obstacles.

### Creating a 3D scene

To create a scene, you need to write the following lines:


![Setting up a basic scene](https://thepracticaldev.s3.amazonaws.com/i/rd75tn38c0vnpfwjhirh.png)


In the code above, we're creating the scene, the camera, the renderer and appending everything to the body.

You can also add lights to your scene. There are different types of lights you can use but in my current prototype, I used an ambient light and spotlight:


![Setting up lights](https://thepracticaldev.s3.amazonaws.com/i/x3b0k07lbqqh3vutzpix.png)


Now we have a basic scene but there's nothing in it. Let's start by generating the landscape we can see in the demo.


### Generating a terrain

Setting up the landscape is a little more complex. It starts with a simple `PlaneGeometry` and `WireframeGeometry`.


![Setting up the main plane](https://thepracticaldev.s3.amazonaws.com/i/totyzw4eelplfjpyzt2j.png)


However, we can see in the demo that we have an effect of generative "mountains". To do this, we need to play with the vertices of our `PlaneGeometry`.


![Making the generative terrain](https://thepracticaldev.s3.amazonaws.com/i/zw0ecw2kbmggwqkox3h2.png)

Using our geometries previously defined, we're going to use the `SimplexNoise` script to help us create an effect of wavy terrain by manipulating the vertices.

To have this effect be continuous throughout the game, we need to call this function with `requestAnimationFrame`.

Now that we have a terrain, we also need to add some rocks (obstacles) and the hoverboard.



### Loading 3D models

The rocks and the skateboard are 3D models. To load them, we need the following lines:

![skate](https://thepracticaldev.s3.amazonaws.com/i/evibddjgb835xgkcuod7.png)


With the lines above, we create an `OBJLoader`, we give it the path to our `.obj` file and we set its size & position in the scene. We also set a color material, and finally, we add it to the scene.

The code for the rocks is pretty much the same.


![Setting up the obstacle model](https://thepracticaldev.s3.amazonaws.com/i/r7r3m5n4wu9uqaqpzk9m.png)

So, we've covered how to create a simple scene, add a procedural terrain, 3D models, but we're missing the interactive part.


### Making it interactive

Now that we have our scene set up, we can use the orientation data we talked about previously to update the position of the hoverboard model in our scene.

To do so, we need code like this:

![Move the hoverboard with orientation data](https://thepracticaldev.s3.amazonaws.com/i/6333pasulbpfw540kdz2.png)

This code sample is similar to the one showed a bit earlier in this tutorial except that now we have our `skateboard` available in our scene so we are able to change its position based on the data coming back from our phone!

---

As said before, there's a bit more code than this for the full experience but in terms of core concepts, that's it! 😃🎉

If you want to check the code, here's the **[Github repo](https://github.com/charliegerard/hvbrd-sockets)**. Otherwise here's the **[live demo](https://bit.ly/hvbrd)**!

Hope you find it fun! 😊👋

---