Building a Browser-based Game w/ a Phone Controller

5 min read Michael Carroll on Nov 12, 2014

You may already know how others are using PubNub to create amazing second screen experiences. Viggle is a social mobile app that rewards you for checking in and interacting with content taking place on TV. Manchester City Matchday Centre is a web app that streams real-time updates and statistics to fans, and works on phones, desktop, and tablets.

However, second screen experiences need not be limited to television or football matches. Recently, there has been a surge in second screen gaming. Nintendo’s latest console, the Wii U, is completely centered around the second screen experience, and some games on Sony’s PlayStation 4 allow you to use a PlayStation Vita as a second screen.


Some of Google’s Chrome Experiments also utilize a phone as a second screen for various web games. World Wide Maze turns a website into a 3D maze, which you then have to find your way out of using your mobile phone as a controller. Roll It lets you use your phone as a controller to play skeeball.

In this tutorial, we’ll walk you through how you can use PubNub to build second screen capabilities into a game. In our Pong example, users can open the game in a web browser, scan the QR code onto their phone, and control the game with their phone controller. We’ll show you how easy it is to build a second screen game, with real-time signaling using PubNub Data Streams.

PongNub: Second Screen Phone Controller Demo

Play the live second screen Pong demo here, and check out the complete source on GitHub. Just scan the QR code with your phone and the game will automatically begin.


Getting Started

We begin this tutorial with an already finished implementation of the game of Pong. Currently, you control the paddles with the arrow keys, and start the game by hitting the enter key. Once the game ends, you can restart it by just hitting the enter key.

Now, the first thing we’ll want to do on our quest for a second screen gaming experience is to disable these old controls, which will render our game unplayable for the time being. Do not despair though.

Browser-based Game

Soon we’ll be able to control the pong paddle with our MIND! phone.

In fact, we probably want to remove the default way the game starts too. Instead of starting the game with an enter key, we’ll start whenever someone pairs a phone to an instance of the game, which we can accomplish with Presence.

The last default action we’ll want to change is what happens when a player wins, i.e. when they score 10 points. Perhaps a modal should pop out on the phone screen, asking the player if he wants to play another match. Or we could automatically restart the game after a countdown. There are many possible choices, but we don’t necessarily have to pick one right now. We can decide on a proper course of action when the time comes. For now, we just have to disable the default behavior that occurs when the game ends.

Pairing: Transferring Data Between a Phone Controller and Browser

The first question we’re going to have to answer is how are actions performed on the phone/controller going to be sent to our game? Of course we have PubNub to facilitate the actual transfer of data, but then we have to ask what channel should this data be sent and received on? If we just hardcoded a channel, then only one instance of the game could be played at a time. So obviously, we should just randomly generate a channel, like so:

But if the channels are randomly generated, how would the game and the controller know which one they should be published on?

To solve this dilemma, we can take a cue from some of the second screen apps I mentioned in the beginning of this tutorial (such as the World Wide Maze). We can add a parameter to the URL of the link to the controller that contains the random 4 digit number we generated, like this .../controller?id=1234.

We can also generate a QR code to this URL with JavaScript, using QRCode.js.

Then when the player goes to the link by scanning the QR code with his phone, the controller can just grab this parameter with some simple JavaScript, so it knows which channel it should publish on.

Building the Phone Controller

Browser-based Game

Now let’s begin working on the controller itself. Our second screen controller is going to be rather simplistic in appearance. It’ll consist of two opposite facing arrows that are scaled to fit any window size with jQuery.

Then we’ll just attach some event listeners to the entire document, which will publish “touchstart”, “touchend”, “touchleave”, and “touchcancel” events onto the PubNub channel we get from the URL parameter. If we also want the game to work for anyone who doesn’t have a phone handy, we can attach event listeners to “mousedown”, “mouseup”, and “mouseleave” events too.

We could send the entire event object in our messages, but that’s really just wasting bandwidth. Instead we’ll break down the events, and only publish the info that our game really needs to function properly, i.e. “touchstart” on the “up” arrow.

Also, notice that you don’t have to be subscribed to a channel to publish to it! But we’ll want to subscribe to the channel, so that our game client can know when a phone is connected to the game.

Message Handling: Connecting the Dots

Now that our controller is going to be sending us data, it’s time for us to connect the dots game side. This is about as easy as connecting literal dots on a literal sheet of paper with a literal crayon. “up” and “touchstart”? Move the paddle up. “down” and “touchend”? Stop moving the paddle down.

Now we’re ready to play Pong on our second screen! Well, we’re almost ready. If you tried to play the game right now, you would notice something strange…

Nothing happens, because we still need to handle how our game should start!

Starting a New Game

Browser-based GameWe’re going to want to start our game as soon as a phone connects to our PubNub Channel, so let’s use Presence. To do so, enable Presence using your demo keys in the Developer’s Portal.

The Function here_now returns a list of uuids currently subscribed to the channel, and also an occupancynumber that is the total current occupancy of the channel.

To determine when someone has connected their phone to our Pong Game, let’s set up an interval that will repeatedly call here_now, and if the occupancy is greater than 1 (since the game is also subscribed to the channel, occupancywill be 2 when a phone connects), start the game.

When the game ends, let’s just pop up a modal that asks the user if he wants to play again.

Now our game is finally ready! Play it here, and check out the complete source on GitHub!

You may be thinking that it’d be pretty easy to extend the ideas presented in this blog to make not just a second screen experience, but a multiplayer experience, and you would be right! Check out some of these older classic blog posts that explain how you can use PubNub to build real time multiplayer games.