Tuesday, 22 June 2010

Accessing Joysticks from JavaScript

Many years ago I wrote a simple browser plug-in to access game controllers from JavaScript. It was Windows only, worked in IE and Netscape 4, and it was used by quite a few JavaScript games at the time (with thousands downloads per day at its peak in 2001, mostly thanks to Scott Porter's JavaScript games). Years passed and it remained largely forgotten, with a few folks still finding it useful for robotics and other specialised cases, but no longer for games. Last year I found myself interested in the project again and decided to update the code, developing versions for Firefox on Windows and Safari on OS X, with the source to all now available under an LGPL license on Google Code (along with prebuilt installers).

Examples of using it from JavaScript, Flash and Java can be found in the project's examples folder; they're quite simple and documented, but in brief, to use it from JavaScript add joystick.js to your page:

<script type="text/javascript" src="joystick.js"></script>

Then create a new Joystick instance, which takes care of inserting the correct type of plug-in into the browser (ActiveX control for IE, NPAPI plug-in for everything else):

var joy = new Joystick();

That's about it! Using it in your game is a matter of reading the controller's axes and buttons wherever you would normally read the keys:

var joyX = joy.getX();
var joyY = joy.getY();

Using it from Flash is slightly more complicated due to having to access plug-ins via ExternalInterface, but the ActionScript Joystick class hides most of that away. Accessing it from a Java applet uses LiveConnect, but again the sample code takes care of this.

So, what are you waiting for? Bring on the games!


Richard said...

Is there any chance of updating this to work in Google Chrome? What would I have to do to make it work on Chrome?

Rich Baker

Richard said...

I figured it out. The Killer Sheep Sample app has a bug in the function() code for Chrome.
if (ctrlFF.setDevice(0) != null)
causes an error, but if you return ctrlFF in the catch section, everything works fine.

Carl Woffenden said...

It was tested successfully with Chrome at the time of posting, so I guess something broke in the meantime. If you have a device connected, what does Chrome return from setDevice? Anything or does it always end up in the catch block?



Richard said...

Thank you for your reply. As near as I can tell, it does not return anything. It simply winds up in the catch block.

Carl Woffenden said...

I meant to add "afterwards". Once you have it working in Chrome (i.e. you've returned ctrlFF) what happens when you call setDevice then?

Richard said...


I am sorry it took me so long to reply. We had to deploy the project and I just got back to this issue. At this point, I can not reproduce the original problem. setDevice(0) in line 172 returns TRUE.

Thank you for your help,

Rich Baker

Carl Woffenden said...

I made a few changes to the plug-in which might solve the problem you're having with Chrome (I say *might* since I can't reproduce the error, but others have been reporting Chrome oddities and I'm hoping its related).

ritdaw said...

What needs to be installed on OS X for this to work?

Carl Woffenden said...

It used to work in Safari but Apple changed the WebKit plug-in interface with version 10.7. It's on my list of things to fix but just not now.