maxogden/voxel-engine — pull request #96 by deathcap (2014-02-16 00:26:10+00:00)
Title: Change game.buttons to use kb-bindings module

Changes game.buttons to use [kb-bindings](https://www.npmjs.org/package/kb-bindings) - which is based on and compatible with @chrisdickinson's [kb-controls](https://www.npmjs.org/package/kb-controls), but takes it a step further than providing a polling interface, also adding events and reconfigurable bindings.

This functionality is very useful to add here since it allows the game to centrally control the keyboard handling, consistently enabling/disabling capturing as pointer lock is attained/released and providing a unified interface for managing bindings.

Previously, non-polling kb handling code would register its own event handlers on the DOM, for example from @maxogden's [voxel-hello-world](https://github.com/maxogden/voxel-hello-world/blob/ef9d6a9cb2b634e1fda25beb6ae280f9e33c6a90/index.js#L56):

// toggle between first and third person modes
window.addEventListener('keydown', function (ev) {
if (ev.keyCode === 'R'.charCodeAt(0)) avatar.toggle()
})

which works, but if you're typing 'R' in a text control (etc.), the event handler is still executed, so it needs to hook into attain/release interact itself.. which gets messy quickly, plus, the above handler still hardcoded the specific keybinding. With kb-bindings in voxel-engine, you can register a descriptive binding name (e.g. 'pov' — to optionally let the user rebind it with [kb-bindings-ui](https://github.com/deathcap/kb-bindings-ui)), then listen for the appropriate events (which are only sent if enabled, so they don't interfere with modal widgets), and it it all works well.

There may be other solutions to these problems than changing `game.buttons` outright. I also experimented with adding a `kb_module` option to voxel-engine, allowing users to pass in their own kb module, but this was problematic since it cannot be JSON-serialized (similar problem to GH-95). If kb-controls itself https://github.com/chrisdickinson/kb-controls/issues/4 grows these features, that would be an option too, but I think events is probably out of the scope of kb-controls (hence a more expansive module, kb-bindings). Or if voxel- could be rearchitected somehow so that voxel-engine wouldn't depend on kb-, instead vice versa (or not at all?), allowing modules to be easily swapped in or out (similar to gl- vs three.js as @shama describes in https://github.com/voxel/issues/issues/4) with fewer interdependencies, but I'm not sure exactly how that would work (open to suggestions); though at least the change in this PR was sufficient for my purposes =) (currently using in ~8 voxel modules)