Controller UI Script


For the past month or so I've been working on a game called Owari, which is now up on Steam Greenlight. I came across an interesting issue which I felt like documenting here:

As most PC games do nowadays, I was adding controller support to Owari so that you could navigate the whole game using a gamepad. Now, Owari is based off web technology, and fortunately there is a Gamepad API for HTML5. Using this, as well as another library (to help simplify the code) adding gamepad support was fairly easy. At least, when it came to detection/pressing of buttons.

However, adding "gamepad" support to a game isn't as simple as that. I realized I needed to come up with a way to navigate my menus and the game with the controller. My initial idea was simply to add an attribute to every element that would be selectable by the controller (which turns out already exists somewhat as tabindex in HTML) but that seemed to be limited to a strict vertical format, i.e. you would only be able to select items from top to bottom.

What would happen

Once Owari starts a match, you have a 6x2 grid board where you would want to be able to move left/right as well as up or down between different spots on the board. The original idea wouldn't allow you to do something like this. If I had the 3rd column on the first row selected, and wanted to select the same 3rd column but in the 2nd row, I would have to tab/press through columns 4-6 on the first row, then 1-2 on the second row, just to reach it. Not an optimal system.

What I want

So I devised another method. Rather than being stuck in 1 direction, I made a system that allowed you to navigate between rows OR columns. That way, if I pressed down on A3 (Row 1, Column 3) I would be on B3 (Row 2, Column 3). If I were to hit left or right, I would be on A2 or A4, respectively.

And so, rather than a simple data-selectable attribute I want with something more like data-select="1-2" where the first number indicates row, and second represents the column. Then thanks to the DOM structure, I can choose which element is currently active, to know which children with data-select to cycle through. So when I'm on the main menu, I can use .main-menu *[data-select] to get all the elements I want to navigate, and then when the game starts I'll activate all the .gameboard *[data-select] elements.

The JS will parse the row/column, attempting to pick the previous/next element in the same direction (and if none exist, keep trying the next one until I know there's nothing left on that side). I'm sure my code is a little messy, and it certainly helps that my game's UI is quite simple, but everything works now so that's fun. Perhaps in the future I can break this out of my game and make a proper library the public can use.